如何显示具有两个条件的数组的唯一结果



$data中,我有以下值:

结果

[{"id":2,"author":"example@mail.com","id_orders":502},
{"id":2,"author":"example@mail.com","id_orders":503},
{"id":2,"author":"example@mail.com","id_orders":505},
{"id":3,"author":"second-example@mail.com","id_orders":502},
{"id":3,"author":"second-example@mail.com","id_orders":503},
{"id":3,"author":"second-example@mail.com","id_orders":505},
{"id":4,"author":"third-example@mail.com","id_orders":502},
{"id":4,"author":"third-example@mail.com","id_orders":503},
{"id":4,"author":"third-example@mail.com","id_orders":505}]

我想要idid_orders的唯一结果。我想要这9个结果中的3个。我已经试过了,但是它在一个id_orders条件下有帮助。

PHP代码

$result = json_decode($data, true);
$unique_array = [];
foreach($result as $element) {
$hash = $element['id_orders'];
$unique_array[$hash] = $element;
}
$data = array_values($unique_array);

你知道两个人在一起会有什么不同吗?

您可以通过跟踪已经使用的值来做到这一点。免责声明:此解决方案仅在两个条件的唯一值数量相同的情况下才会产生明确的结果。

$uniqueArray = [];
$usedValues = [
'id' => [],
'id_orders' => [],
];
foreach ($result as $element) {
if (!in_array($element['id'], $usedValues['id']) && !in_array($element['id_orders'], $usedValues['id_orders'])) {
$uniqueArray[] = $element;
$usedValues['id'][] = $element['id'];
$usedValues['id_orders'][] = $element['id_orders'];
}
}

基本上,这里发生的事情是我们使用$usedValues来存储我们已经使用过的所有唯一值,并使用in_array与它进行比较。当我们迭代对象时,任何具有idid_orders的对象都将被跳过。配对将按照在数组中出现的顺序进行。

我已经做了额外的努力,使这段代码更通用一点:

* Finds elements with a unique combination of values under given keys.
*
* Assumes all elements in the array are arrays themselves and that the
* subarrays have the same structure. Assumes subarray elements are not
* objects (uses strict comparison).
*/
function uniqueCombination(array $arrayToFilter, array $keysToFilterOn): array
{
if (empty($arrayToFilter) || empty($keysToFilterOn)) {
throw new InvalidArgumentException(
'Parameters of uniqueCombination must not be empty arrays'
);
}
// get the keys from the first element; others are assumed to be the same
$keysOfElements = array_keys(reset($arrayToFilter));
$keysPresentInBoth = array_intersect($keysToFilterOn, $keysOfElements);
// no point in running the algorithm if none of the keys are
// actually found in our array elements
if (empty($keysPresentInBoth)) {
return [];
}
$result = [];
$usedValues = array_combine(
$keysPresentInBoth,
array_fill(0, count($keysPresentInBoth), [])
);
foreach ($arrayToFilter as $element) {
if (!isAlreadyUsed($usedValues, $element)) {
$result[] = $element;
foreach ($keysPresentInBoth as $keyToUse) {
$usedValues[$keyToUse][] = $element[$keyToUse];
}
}
}
return $result;
}
function isAlreadyUsed(array $usedValues, array $element): bool
{
foreach ($usedValues as $usedKey => $usedValue) {
if (in_array($element[$usedKey], $usedValue)) {
return true;
}
}
return false;
}

在其核心,这是相同的算法,但动态。它允许一个可变数量的键来过滤(这就是为什么它们作为参数单独传递),所以$usedValues数组是动态创建的(使用第一个元素的键作为自己的键,填充空数组),所有的键必须在循环中进行比较(因此单独的函数来检查元素的值是否已经被使用)。

它可能在这里或那里进行调整,因为我还没有完全测试过,但应该为大多数结构提供满意的结果。

最新更新