【问题标题】:How can you make a multidimensional array unique?如何使多维数组独一无二?
【发布时间】:2011-06-02 21:09:29
【问题描述】:

我有一个多维数组设置,如下所示:

array(
  [0]=>
  array(
    ["name"]=> "Foo"
    ["slug"]=> "Bar"
  )
  [1]=>
  array(
    ["name"]=> "Foo"
    ["slug"]=> "Bar"
  )
  [2]=>
  array(
    ["name"]=> "Test 1"
    ["slug"]=> "test-1"
  )
  [3]=>
  array(
    ["name"]=> "Test 2"
    ["slug"]=> "test-2"
  )
  [4]=>
  array(
    ["name"]=> "Test 3"
    ["slug"]=> "test-3"
  )
)

在该区域中搜索“name”中的重复值并将其删除以使多维数组中的每个值都是唯一的最佳方法是什么?

提前致谢!

【问题讨论】:

  • 假设您有一个重复的name,但slug 的值会有所不同——您预期结果如何? (应该删除/删除哪个重复项?)
  • @Brad Christie,在这种特殊情况下,名称/slug 组合不会改变。谢谢你的评论! :)
  • 这是一种明智的不回答,但有时最好不要一开始就添加重复项。也就是说,如果您碰巧正在创建这个数组,而不是从您无法控制的某个来源获取,您可以在追加之前测试您的项目是否已经存在。在这种情况下,一个简单的in_array('some_value', array_column($your_array, 'some_key')) 应该可以完成它。

标签: php arrays multidimensional-array unique


【解决方案1】:

您可以使用关联数组。

$temp_array = array();
foreach ($array as &$v) {
    if (!isset($temp_array[$v['name']]))
        $temp_array[$v['name']] =& $v;
}

这将创建一个临时数组,使用 $v['name'] 作为键。如果已经存在具有相同键的元素,则不会将其添加到临时数组中。

您可以将关联数组转换回顺序数组,使用

$array = array_values($temp_array);

示例代码和输出:http://codepad.org/zHfbtUrl

【讨论】:

  • 我喜欢这个,这是一种非常简单和紧凑的工作方式。感谢您的帮助并提供指向工作示例的链接! :)
【解决方案2】:

由于每个人都给出了替代方案,这里有一个解决手头问题的方法。有时我们必须使用我们拥有的数据,而不是按照我们喜欢的方式重新排列它。话虽如此,这将从数组中删除所有重复的后续条目。

$array = Array(
  Array(
    'name'  => 'Test 3',
    'slug'  => 'test-3'
  ),
  Array(
    'name'  => 'Foo',
    'slug'  => 'Bar'
  ),
  Array(
    'name'  => 'Foo',
    'slug'  => 'Bar'
  ),
  Array(
    'name'  => 'Test 1',
    'slug'  => 'test-1'
  ),
  Array(
    'name'  => 'Test 2',
    'slug'  => 'test-2'
  ),
  Array(
    'name'  => 'Test 3',
    'slug'  => 'test-3'
  ),
);
var_dump($array);

for ($e = 0; $e < count($array); $e++)
{
  $duplicate = null;
  for ($ee = $e+1; $ee < count($array); $ee++)
  {
    if (strcmp($array[$ee]['name'],$array[$e]['name']) === 0)
    {
      $duplicate = $ee;
      break;
    }
  }
  if (!is_null($duplicate))
    array_splice($array,$duplicate,1);
}
var_dump($array);

看起来像这样:

array(6) {
  [0]=>
  array(2) {
    ["name"]=>
    string(6) "Test 3"
    ["slug"]=>
    string(6) "test-3"
  }
  [1]=>
  array(2) {
    ["name"]=>
    string(3) "Foo"
    ["slug"]=>
    string(3) "Bar"
  }
  [2]=>
  array(2) {
    ["name"]=>
    string(3) "Foo"
    ["slug"]=>
    string(3) "Bar"
  }
  [3]=>
  array(2) {
    ["name"]=>
    string(6) "Test 1"
    ["slug"]=>
    string(6) "test-1"
  }
  [4]=>
  array(2) {
    ["name"]=>
    string(6) "Test 2"
    ["slug"]=>
    string(6) "test-2"
  }
  [5]=>
  array(2) {
    ["name"]=>
    string(6) "Test 3"
    ["slug"]=>
    string(6) "test-3"
  }
}
array(4) {
  [0]=>
  array(2) {
    ["name"]=>
    string(6) "Test 3"
    ["slug"]=>
    string(6) "test-3"
  }
  [1]=>
  array(2) {
    ["name"]=>
    string(3) "Foo"
    ["slug"]=>
    string(3) "Bar"
  }
  [2]=>
  array(2) {
    ["name"]=>
    string(6) "Test 1"
    ["slug"]=>
    string(6) "test-1"
  }
  [3]=>
  array(2) {
    ["name"]=>
    string(6) "Test 2"
    ["slug"]=>
    string(6) "test-2"
  }
}

【讨论】:

  • 感谢布拉德的解决方案!我喜欢你处理手头问题的观点,这对我有用。尽管我将接受@Gobs 的建议,即查看哈希表,因为我从未这样做过。学习的好机会。 :)
  • 嘿试试这个单线宝贝:$input = array_map('unserialize', array_unique(array_map('serialize', $input)));stackoverflow.com/a/946300/3063226
  • 注意:当我尝试这个实现时,它确实删除了一个重复项。实际上我有一些值一式三份,所以我重复了操作,它确实再次删除了,但我选择了@Heitor 在 cmets 中提供的答案。
  • 这不会删除所有重复项,但只找到第一个重复项,如果有 3 行与名称匹配,则不会删除第三行
【解决方案3】:
$array = array(
    0 => array(
        "name"=> "Foo",
        "slug"=> "Bar"
    ),
    1 => array(
        "name"=> "Foo",
        "slug"=> "Bar"
    ),
    2 => array(
        "name"=> "Test 1",
        "slug"=> "test-1"
    ),
    3 => array(
        "name"=> "Test 2",
        "slug"=> "test-2"
    ),
    4 => array(
        "name"=> "Test 3",
        "slug"=> "test-3"
    )
);



function array_unique_by_key (&$array, $key) {
    $tmp = array();
    $result = array();
    foreach ($array as $value) {
        if (!in_array($value[$key], $tmp)) {
            array_push($tmp, $value[$key]);
            array_push($result, $value);
        }
    }
    return $array = $result;
}

array_unique_by_key($array, "name");

【讨论】:

    【解决方案4】:

    仅查看您的特定情况,我建议使用哈希表而不是二维数组。如果您使用您的“姓名”作为散列中的键,则每个条目都是唯一的。

    对多维数组有特殊需求吗?

    【讨论】:

    • 从未使用过哈希表,但我肯定会按照您的建议进行研究。对多维数组没有特别的需求,这正是我当时准备数据的方式。感谢您的建议和帮助。 :)
    【解决方案5】:
    function multi_array_unique_by_value($array, $colon = '')
    {
        $ret_array = array();
        $has_array = array();
        foreach($array as $item)
        { 
            $item_array = (array)$item;
            if(!in_array($item_array[$colon], $has_array))
            {
                array_push($ret_array, $item);
                array_push($has_array, $item_array[$colon]);
            }
        }
        return $ret_array;
    }
    

    你可以在这里给你的数组,并给一个冒号名称以使其唯一。

    在这段代码中,你有一个多维数组,我们foreach那个数组,为我们提供哪一列的索引,我们推送那一列的值。当值相同时,它不添加返回数组。

    因此,此解决方案适用于 1 列的 array_unique。

    【讨论】:

    • 能否更好地解释这里发生了什么?
    【解决方案6】:

    为您的多维数组提供更简单的解决方案。

    $unique = array_map('unserialize', array_unique(array_map('serialize', $array)));
    
    echo "<pre>";
    print_r($unique);
    

    【讨论】:

    • 如果您将数据存储在数据库中,也可以使用array_map("json_decode", array_unique(array_map("json_encode", $final)))
    • 我们需要这个复制粘贴的重复建议吗? stackoverflow.com/a/946300/2943403您的意思是投票结束作为重复而不是回答这个问题?
    猜你喜欢
    • 2023-04-10
    • 1970-01-01
    • 2018-01-27
    • 2011-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-09
    • 1970-01-01
    相关资源
    最近更新 更多