开发者

php - How do I weed out similar items from an associative array?

UPDATE: someone edited my question incorrectly, but it's fixed now

Let's say I have the following associative array:

Array ( 
[Postponement no issue for Man Utd (BBC) ] => 8 
[Postponement no issue for Man Utd ] => 7 
[Postponement no issue for Man Utd: Man开发者_StackOverflow社区chester United say they have no issue over Sunday's game at Chelsea being ... ] => 3
)

You'll notice that the term "Postponement no issue for Man Utd" appears in all three keys. I want to turn this array into a new array like this:

Array ( [Postponement no issue for Man Utd] => 18 )

Where 18 is the sum of all values where the key contains "Postponement no issue for Man Utd".

In other words: if one key appears inside another key, the latter is dropped fom the new array and it's value is added on to the former key's value.

Is this possible and how? Thanks in advance.


Depending on the size of your data this may not be feasible. There is almost certainly a more optimal solution, but this works:

<?php
$array = array(
    'Postponement no issue for Man Utd (BBC)' => 8, 
    'Postponement no issue for Man Utd' => 7,
    'Postponement no issue for Man Utd: Manchester United say they have no issue over Sunday\'s game at Chelsea being ...' => 3
);

$keys = array_keys($array);
usort($keys, 'lengthCmp');
$flippedKeys = array_flip($keys);

$data = array();

foreach ($keys as $k => $v)
{
 $sum = 0;

 foreach ($array as $key => $val)
 {
  if (stripos($key, $v) !== FALSE)
  {
   $sum += $val;
   unset($array[$key]);
   unset($keys[$flippedKeys[$v]]);
  }
 }

 $data[$v] = $sum;
}

foreach ($data as $key => $val)
{
 if ($val == 0)
  unset($data[$key]);
}

var_dump($data);

function lengthCmp($a, $b)
{
 return strlen($a) - strlen($b);
}
?>

Output:

array(1) {["Postponement no issue for Man Utd"] => int(18)}

And with this data set:

$array = array(
    'test test' => 1,
    'Postponement no issue for Man Utd (BBC)' => 8, 
    'Postponement no issue for Man Utd' => 7,
    'Postponement no issue for Man Utd: Manchester United say they have no issue over Sunday\'s game at Chelsea being ...' => 3,
    'test' => 1,
    'not here' => 1,
    'another test' => 1
);

Output:

array(3) {
    ["test"] => int(3)
    ["not here"] => int(1)
    ["Postponement no issue for Man Utd"] => int(18)
}


foreach($array as $k1 => $v1)
        foreach($array as $k2 => $v2)
             if(strpos($k2, $k1) !== false) // or === 0
                   $result[$k1] = (isset($result[$k1]) ? $result[$k1] : 0) + $v2;

untested


A simple approach could be:

$original_array = array(...); // The original array with keys and values
asort($original_array); // Sort the array by its keys
$clean_array = array();
foreach ($original_array as $key => $value)
{
  foreach (array_keys($clean_array) as $clean_key)
  {
    $found = false;

    if (preg_match('/'.preg_quote($clean_key).'/', $key))
    {
      $clean_array[$clean_key] += $value;
      $found = true;

      break;
    }

    if (!$found) $clean_array[$key] = $value;
  }
}


Ok... the only way to do this is to iterate through the array twice, and have a function compare them:

foreach ($my_array as $key1 => $value1) {
    foreach ($my_array as $key2 => $value2) {
        if ($key1 != $key2) { // don't compare them if they're the same
            if (compareKeys($key1,$key2)) {
                $my_array[$key1] += $value2;
                unset($my_array[$key2]);
            }
        }
    }
}

Then your compareKeys function could look something like this:

function compareKeys($val1,$val2) {
    return (strpos($val1,$val2)!==false);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜