我怎么能用更短的方式写这个? [关闭]

This code repeats itself. How can I make it shorter? Maybe by using anonymous function or something?

foreach ($value as $wrong) {
  if (starts_with($wrong, '%') and ends_with($wrong, '%')) {
    $wrong = trim($wrong, '%');
    if (contains($address, $wrong)) {
      $corrected_address = str_replace($wrong, $key, $address);
      break;
    }
  }
  else {
    $wrong = trim($wrong, '%');
    if (ends_with($address, $wrong)) {
      $corrected_address = str_replace($wrong, $key, $address);
      break;
    }
  }
}

Thanks.

Here's my stab at a shorter version:

foreach ($value as $wrong) {
   $both  = starts_with($wrong, '%') && ends_with($wrong, '%');
   $wrong = trim($wrong, '%');
   if ($both ? contains($address, $wrong) : ends_with($address, $wrong)) {
      $corrected_address = str_replace($wrong, $key, $address);
      break;
   }
}

$both should probably be renamed to something more descriptive.

How about this:

foreach ($value as $wrong) { 
  $wrong = trim($wrong, '%');

  if (starts_with($wrong, '%') && ends_with($wrong, '%')) { 

    if (contains($address, $wrong)) { 
      $corrected_address = str_replace($wrong, $key, $address); 
      break; 
    } 

  }elseif (ends_with($address, $wrong)) { 
      $corrected_address = str_replace($wrong, $key, $address); 
      break; 
  } 
} 

You don't need a loop if you're breaking after the first one. You can use array_filter to get the matches and then do something with the first one.

$trimmed = array_map(function($x){return trim($x,'%');}, $value);
$matches = array_filter($trimmed, function($x){return contains($GLOBALS["address"],$x);});
$wrong = array_shift($matches);
$corrected_address = str_replace($wrong, $key, $address);

btw, notice how array_map takes the callback first and the array second but array_filter reverses that? It's things like that that make me avoid php.