如何在关联数组中保留值


how to keep a value in associative array

我在php中有一个关联数组的例子。我想保留元素的两个出现之一。第一个和第二个数组的名称为 Z,因此我想根据键(名称)和分数的特殊条件保留其中一个数组。对我来说最重要的是知道如何去做。这是我做过的一次尝试,但我失败了。

foreach($tabs as $key => $tab){
        if($tab[$key]['name'] != $tab[$key+1]['name']){
      //do some code
  }
}
array(
       [0] => array(
                id => 1,
                name => Z
                score => 77
         )
       [1] => array(
                id => 2,
                name => Z
                score => 10
         )
      [2] => array(
                id => 3,
                name => A
                score => 55
         )
);

我想保留这样的数组:

 array(
       [0] => array(
                id => 1,
                name => Z
                score => 77
         )
      [2] => array(
                id => 3,
                name => A
                score => 55
         )
);

谢谢

我会选择这样的东西:

<?php
$original_data = array(
    0 => array(
        'id' => 1,
        'name' => 'Z',
        'score' => 77
    ),
    1 => array(
        'id' => 2,
        'name' => 'Z',
        'score' => 10
    ),
    2 => array(
        'id' => 3,
        'name' => 'A',
        'score' => 55
    )
);
$highest = array();
$to_be_removed = array();
foreach($original_data as $key => &$tab)
{
    if(isset($highest[$tab['name']]['score']))
    {
        if($tab['score'] > $highest[$tab['name']]['score'])
        {
            $to_be_removed[$highest[$tab['name']]['index']] = '';
            $highest[$tab['name']]['score'] = $tab['score'];
            $highest[$tab['name']]['index'] = $key;
        }
        else
        {
            $to_be_removed[$key] = '';
        }
    }
    else
    {
        $highest[$tab['name']]['score'] = $tab['score'];
        $highest[$tab['name']]['index'] = $key;
    }
}
if($to_be_removed)
{
    foreach($to_be_removed as $k=>&$v)
    {
        unset($original_data[$k]);
    }
}
print_r($original_data);
你可以

in_array()来找它,但是这个函数不是递归的,所以你需要自己做函数,像这样:

function in_array_r($needle, $haystack, $strict = false) {
    foreach ($haystack as $item) {
        if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict))) {
            return true;
        }
    }
    return false;
}

你可以像这样使用它:

foreach($tabs as $key => $tab){
  if(in_array_r($tab['name'], $tabs){
      // it found in the whole array
      unset($tabs[$key]);
  } 
}

你可以做

$new = [];
foreach ($tabs as $tab) {
    if (! isset($new[$tab['name']])) {
        $new[$tab['name']] = $tab;
    }
}
$new = array_values($new);

这是一个两步解决方案,其优点是不必为每个检查迭代整个数组。

如果您需要检查是否覆盖的条件(分数值等),

foreach ($tabs as $tab) {
    if ( (! isset($new[$tab['name']]))
         || shouldOverwrite($new[$tab['name'], $tab)
    ) {
        $new[$tab['name']] = $tab;
    }
}

您应该定义function shouldOverwrite($old, $new)将迭代中的存储与当前存储的进行比较,以及您希望实现的任何比较逻辑。

您可以通过nameunset()包含此元素的子数组进行比较。

$arr = array(
    0 => array(
        id => 1,
        name => Z,
        score => 77
    ),
    1 => array(
        id => 2,
        name => Z,
        score => 10
    ),
    2 => array(
        id => 3,
        name => A,
        score => 55
    )
);
$name = '';
foreach($arr as $key=>$val){
    if($name == $val['name']){
        unset($arr[$key]);
    }else{
        $name = $val['name'];                
    }
}
print_r($arr);

输出为:

Array
(
    [0] => Array
        (
            [id] => 1
            [name] => Z
            [score] => 77
        )
    [2] => Array
        (
            [id] => 3
            [name] => A
            [score] => 55
        )
)

尝试一个好的 ol' unset:

foreach($tabs as $key => $tab){
        if (isset($tab[$key-1] && $tab[$key]['name'] != $tab[$key-1]['name']){    
            //do some code
        } elseif (isset($tab[$key-1])) && $tab[$key]['name'] == $tab[$key-1]['name']) { 
             unset($tab[$key-1]);
        }
  }
}

仅当项目相邻时,这才有效。如果它们不相邻,您可以首先对数组进行排序以确保它们:

usort($tabs, function ($v1,$v2) {
   return strcmp($v1['name'], $v2['name']);
});