Предположим, мы делаем какую-то очистку, и в итоге мы можем получить как дублированные, так и полудублированные результаты.
Учитывая входной массив, который может выглядеть примерно так:
$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',
],
];
Я пробовал несколько разных решений, и мне не нравится ни одно из них. Независимо от того, как я к этому отношусь, это похоже на клочок, и я чувствую, что мне не хватает очевидного и элегантного решения.
Я знаю, что у кого-то будет хорошее предложение для чего-то более чистого, чем сортировка, циклы и фильтрация, которые я пробовал.
Вы можете сделать это так:
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);
Вы создаете новый ассоциативный массив, используя заголовок в качестве ключа. Вы зацикливаете исходный массив, когда ключ существует, вы проверяете, является ли длина дескриптора большей, и продолжаете в противном случае, вы заменяете элемент в массиве результатов на текущий элемент.
Вы также можете использовать 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);
Других решений пока нет …