如何使用两个键删除数组中的重复项?
Posted
技术标签:
【中文标题】如何使用两个键删除数组中的重复项?【英文标题】:How to remove duplicates in an array using two keys? 【发布时间】:2012-12-11 04:20:14 【问题描述】:以下脚本将根据单键从数组中删除重复项。我通过以下参考找到了它。 参考:remove duplicates from array (array unic by key)
我遇到的问题是 $initial_data 数组可能包含具有相同 [Post_Date] 值但不同 [Item_Title] 值的项目.
有没有办法修改代码,使其仅在 [Post_Date] 和 [Item_Title] 值相同的情况下删除重复项?
// Remove Duplicates based on 'Post_Date'
$_data = array();
foreach ($initial_data as $v)
if (isset($_data[$v['Post_Date']]))
continue;
$_data[$v['Post_Date']] = $v;
// if you need a zero-based array, otherwise work with $_data
$unique_results = array_values($_data);
下面是显示 4 个字段的数组的简化输出。原始数组包含 16 个字段。
$initial_data:原始数据数组。 [Post_Date] 值相同,但 [Item_Title] 值不同。
Array
(
[0] => Array
(
[id] => 22000
[Category] => vehicles
[Post_Date] => 1356373690
[Item_Title] => Car Painting
)
[1] => Array
(
[id] => 22102
[Category] => vehicles
[Post_Date] => 1356373690
[Item_Title] => Car Repair
)
...
)
$_data:脚本中的 $_data 数组
Array
(
[1356373690] => Array
(
[id] => 22000
[Category] => vehicles
[Post_Date] => 1356373690
[Item_Title] => Car Painting
)
[1356373690] => Array
(
[id] => 22102
[Category] => vehicles
[Post_Date] => 1356373690
[Item_Title] => Car Repair
)
...
)
$unique_results:最终的唯一结果数组。如您所见,脚本仅根据 [Post_Date] 删除了重复的数组项,但我还需要它来评估 [Item_Title] 值是否不同或相同,以便它不会将此数组项视为重复项。
Array
(
[0] => Array
(
[id] => 22000
[Category] => vehicles
[Post_Date] => 1356373690
[Item_Title] => Car Painting
)
...
)
【问题讨论】:
@Mike Brant 我什么都没试过。上面的代码适用于 1 个键,但我需要为 2 个键修改它。我也尝试了下面的两个建议,但都没有奏效。 【参考方案1】:你可以用嵌套循环解决这个问题
$uniqueData = array();
foreach ($initialData as $item)
$exists = false;
// check if same item was already added to uniqueData array
foreach ($uniqueData as $uniqueItem)
if($item['postDate'] == $uniqueItem['postDate'] && $item['itemTitle'] == $uniqueItem['itemTitle'])
$exists = true;
// there is no same item in uniqueData array
if(!$exists)
$uniqueData[] = $item;
print_r($uniqueData);
附带说明,在大多数情况下,最好避免使用 continue
语句,因为它会使您的代码更难阅读。
【讨论】:
这至少可以说是低效的。首先,您跳过了使用散列函数快速查找现有项目的可能性。其次,您没有在找到项目时中断循环(因此每次搜索都会一次又一次地遍历整个$uniqueData
数组)。最后,您在continue
上的声明是……奇怪,至少可以说:默认情况下,此操作没有任何问题或“不可读”,这完全取决于它的使用方式。
@kustrle 试了一下,处理过程大约需要 30 秒,最终得到一个空数组 Array()。我用我的数组 $results 替换了你的变量 $initialData,用我的 Post_Date 替换了你的 postDate,在你的代码中用我的 Item_Title 替换了你的 itemTitle。
我用 4 个项目运行它,它运行良好,没有延迟。 @raina77ow 他没有要求有效的解决方案。过早的优化是万恶之源。如果他没有很多项目,代码将运行得很好。关于继续声明,我可以以您的回答为例。写 if (!isset($_data[$key])) $_data[$key] = $v;看起来比 continue 干净得多。
这是一个演示 sandbox.onlinephpfunctions.com/code/…【参考方案2】:
我想,最简单的方法是使用这两个属性的简单串联作为$data
哈希的键:
$key = $v['Post_Date'] . $v['Item_Title'];
if (isset($_data[$key]))
continue;
$_data[$key] = $v;
如果 Post_Date 和 Item_Title 可以“重叠”,这显然是行不通的——但从给定的示例中似乎不可能。为了防止这种情况,您可以在 $key
中插入一个分隔符,如下所示:
$key = $v['Post_Date'] . ':' . $v['Item_Title'];
...作为冒号符号显然不会用于存储时间戳字符串。
【讨论】:
以上是关于如何使用两个键删除数组中的重复项?的主要内容,如果未能解决你的问题,请参考以下文章
Vuejs - 如何使用 v-for 获取数组中的所有唯一值(删除重复项)