如何在关联数组中保留一个值

时间:2016-03-01 15:56:18

标签: php arrays

我在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
         )
);

由于

5 个答案:

答案 0 :(得分:1)

您可以使用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]);
  } 
}

答案 1 :(得分:1)

你可以做到

$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)将存储与迭代中的当前比较与您希望实现的任何比较逻辑进行比较。

答案 2 :(得分:1)

我会选择这样的事情:

<?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);

答案 3 :(得分:0)

您可以按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
        )

)

答案 4 :(得分:0)

尝试一个好的'未设置:

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']);
});