如何根据 PHP 中的键清除具有半重复值的数组数组?

Posted

技术标签:

【中文标题】如何根据 PHP 中的键清除具有半重复值的数组数组?【英文标题】:How to Clean Up Array of Arrays with Semi-duplicate Values Base on Keys in PHP? 【发布时间】:2018-08-21 20:01:16 【问题描述】:

假设我们正在执行某种类型的抓取,最终我们可以获得重复和半重复的结果。

给定一个可能看起来有点像这样的输入数组:

$inputArr = [
  [
    'title' => 'Test0',
    'desc'  => 'Short Desc',
  ],
  [
    'title' => 'Test5',
    'desc'  => 'Short Desc',
  ],
  [
    'title' => 'Test0',
    'desc'  => 'Much Longer Than Short Desc',
  ],
  [
    'title' => 'Test0.5',
    'desc'  => 'Short Desc',
  ],
  [
    'title' => 'Test1',
    'desc'  => 'Short Desc',
  ],
  [
    'title' => 'Test1',
    'desc'  => 'Much Longer Than Short Desc',
  ],
  [
    'title' => 'Test1.5',
    'desc'  => 'Much Longer Than Short Desc',
  ],
  [
    'title' => 'Test3',
    'desc'  => 'Short Desc',
  ],
  [
    'title' => 'Test2',
    'desc'  => 'Short Desc',
  ],
  [
    'title' => 'Test3.75',
    'desc'  => 'Much Longer Than Short Desc',
  ],
  [
    'title' => 'Test3.25',
    'desc'  => 'Short Desc',
  ],
  [
    'title' => 'Test2',
    'desc'  => 'Much Longer Than Short Desc',
  ],
  [
    'title' => 'Test3',
    'desc'  => 'Much Longer Than Short Desc',
  ],
  [
    'title' => 'Test5',
    'desc'  => 'Much Longer Than Short Desc',
  ],
  [
    'title' => 'Test3.5',
    'desc'  => 'Short Desc',
  ],
  [
    'title' => 'Test4',
    'desc'  => 'Short Desc',
  ],
  [
    'title' => 'Test5',
    'desc'  => 'Much Longer Than Short Desc',
  ],
  [
    'title' => 'Test4.5',
    'desc'  => 'Short Desc',
  ],
  [
    'title' => 'Test4',
    'desc'  => 'Much Longer Than Short Desc',
  ],
  [
    'title' => 'Test5',
    'desc'  => 'Much Longer Than Short Desc',
  ],
];

生成的数组必须只包含一个具有title 值实例的数组,其中desc 是最长的字符串值,同时删除除desc 具有与其他字符串长度值相等的值之外的所有数组。

例如最终输出应如下所示:

$resultArr = [
  [
    'title' => 'Test0',
    'desc'  => 'Much Longer Than Short Desc',
  ],
  [
    'title' => 'Test0.5',
    'desc'  => 'Short Desc',
  ],
  [
    'title' => 'Test1',
    'desc'  => 'Much Longer Than Short Desc',
  ],
  [
    'title' => 'Test1.5',
    'desc'  => 'Much Longer Than Short Desc',
  ],
  [
    'title' => 'Test2',
    'desc'  => 'Much Longer Than Short Desc',
  ],
  [
    'title' => 'Test3',
    'desc'  => 'Much Longer Than Short Desc',
  ],
  [
    'title' => 'Test3.25',
    'desc'  => 'Short Desc',
  ],
  [
    'title' => 'Test3.5',
    'desc'  => 'Short Desc',
  ],
  [
    'title' => 'Test3.75',
    'desc'  => 'Much Longer Than Short Desc',
  ],
  [
    'title' => 'Test4',
    'desc'  => 'Much Longer Than Short Desc',
  ],
  [
    'title' => 'Test4.5',
    'desc'  => 'Short Desc',
  ],
  [
    'title' => 'Test5',
    'desc'  => 'Much Longer Than Short Desc',
  ],
];

我尝试了几种不同的解决方案,但我都不喜欢其中任何一种。不管我是怎么想的,这感觉就像是一团糟,我觉得我错过了一个明显而优雅的解决方案。

我知道有人会对比我尝试过的排序、循环和过滤更干净的东西提出很好的建议。

【问题讨论】:

分享您的解决方案,说明为什么它不起作用。 我同意。向我们展示您尝试了什么以及为什么它不起作用。解决这个问题大约需要 5-10 分钟,但我们不是来“为您编写代码”的。 如果您使用以标题为键的关联数组而不是二维数组,事情会变得容易得多。 【参考方案1】:

你可以这样做:

foreach($inputArr as $item) 

    if ( isset($result[$item['title']]) && strlen($result[$item['title']]['desc']) > strlen($item['desc']) )
        continue;    

    $result[$item['title']] = $item;


$result = array_values($result);

print_r($result);

demo

您使用标题作为键构建一个新的关联数组。循环原始数组,当键存在时,检查 desc 的长度是否更长,否则继续,将结果数组中的项替换为当前项。

你也可以使用array_reduce:

$result = array_reduce($inputArr, function ($c, $i) 
    if ( !isset($c[$i['title']]) || strlen($c[$i['title']]['desc']) < strlen($i['desc']) )
        $c[$i['title']] = $i;

    return $c;
);


$result = array_values($result);

print_r($result); 

【讨论】:

@Devon: array_values 只是按照要求将$result 从关联数组更改为索引数组。

以上是关于如何根据 PHP 中的键清除具有半重复值的数组数组?的主要内容,如果未能解决你的问题,请参考以下文章

php数组的重复值如何过滤掉

PHP获取数组中重复值的键值

JavaScript:检查对象数组中是不是存在重复的键值并删除所有但最近添加的具有该键值的对象

返回具有给定短语(数组)值的键

PHP如何根据数组中的键值进行排序

如何从 php 数组中删除具有特定值的所有元素? (以尽可能最短的方式)[重复]