gpt4 book ai didi

php - 在 PHP 中,如何删除对象数组中的重复项,其中重复项定义为具有相同值的键值对的子集

转载 作者:行者123 更新时间:2023-12-04 01:25:43 30 4
gpt4 key购买 nike

我有一个形式的数组:

class anim {
public $qs;
public $dp;
public $cg;
public $timestamp;
}
$animArray = array();

$myAnim = new anim();
$myAnim->qs = "fred";
$myAnim->dp = "shorts";
$myAnim->cg = "dino";
$myAnim->timestamp = 1590157029399;
$animArray[] = $myAnim;

$myAnim = new anim();
$myAnim->qs = "barney";
$myAnim->dp = "tshirt";
$myAnim->cg = "bird";
$myAnim->timestamp = 1590133656330;
$animArray[] = $myAnim;

$myAnim = new anim();
$myAnim->qs = "fred";
$myAnim->dp = "tshirt";
$myAnim->cg = "bird";
$myAnim->timestamp = 1590117032286;
$animArray[] = $myAnim;

如何创建一个仅包含 $animArray 的非重复项(以及找到重复项的最新条目)的新数组,其中重复项定义为:

其中 $myAnim->dp 与另一个数组元素的 $myAnim->dp$myAnim->cg< 具有相同的值 来自第一个和 $myAnim->cg 来自第二个具有相同的值。

在上面的示例中,只有第一个元素根据该定义是唯一的。

我希望有一个优雅的解决方案。我已经阅读了 PHP 手册中的所有数组函数,但看不到它是如何实现的。

我可以遍历每个数组元素,检查 $myAnim->dp 是否与另一个数组元素的 $myAnim->dp 具有相同的值,保存匹配项进入一个新数组,然后循环遍历该新数组,检查其 $myAnim->cg 是否与该新数组中任何其他元素的 $myAnim->cg 匹配。

一个更优雅的解决方案将允许我更改确定是否存在重复的键值对组合,而无需重新编写很多代码。

是否存在这样的解决方案?

感谢您帮助这个新手:)

最佳答案

虽然没有内置的东西可以直接开箱即用,但也不需要大量代码来处理任意数量的属性来考虑其唯一性。通过跟踪查找数组中的每个唯一属性,我们可以构建一个数组,其中叶节点(即那些本身不是数组的节点)是对象。

我们通过在数组中保留对当前级别的引用 (&) 来实现这一点,然后继续为每个属性构建我们的查找数组。

function find_uniques($list, $properties) {
$lookup = [];
$unique = [];
$last_idx = count($properties) - 1;

// Build our lookup array - the leaf nodes will be the items themselves,
// located on a level that matches the number of properties to look at
// to consider a duplicate
foreach ($list as $item) {
$current = &$lookup;

foreach ($properties as $idx => $property) {
// last level, keep object for future reference
if ($idx == $last_idx) {
$current[$item->$property] = $item;
break;
} else if (!isset($current[$item->$property])) {
// otherwise, if not already set, create empty array
$current[$item->$property] = [];
}

// next iteration starts on this level as its current level
$current = &$current[$item->$property];
}
}

// awr only calls the callback for leaf nodes - i.e. our items.
array_walk_recursive($lookup, function ($item) use (&$unique) {
$unique[] = $item;
});

return $unique;
}

使用上面的数据调用,要求是唯一的并且返回重复项的最后一个元素,我们得到以下结果:

var_dump(find_uniques($animArray, ['dp', 'cg']));

array(2) {
[0] =>
class anim#1 (4) {
public $qs =>
string(4) "fred"
public $dp =>
string(6) "shorts"
public $cg =>
string(4) "dino"
public $timestamp =>
int(1590157029399)
}
[1] =>
class anim#3 (4) {
public $qs =>
string(4) "fred"
public $dp =>
string(6) "tshirt"
public $cg =>
string(4) "bird"
public $timestamp =>
int(1590117032286)
}
}

在您的示例中映射到元素 [0] 和元素 [2]。如果您想保留第一个对象以备重复,请添加一个 isset,如果属性值已被看到则终止内部循环:

foreach ($properties as $idx => $property) {
if ($idx == $last_idx) {
if (isset($current[$item->$property])) {
break;
}

$current[$item->$property] = $item;
} else {
$current[$item->$property] = [];
}

// next iteration starts on this level as its current level
$current = &$current[$item->$property];
}

重要的是要注意,这是在假设您要检查唯一性的数组本身不包含数组的情况下编写的(因为我们正在使用 -> 查找属性并且因为我们正在使用 array_walk_recursive 来查找任何不是数组的东西)。

关于php - 在 PHP 中,如何删除对象数组中的重复项,其中重复项定义为具有相同值的键值对的子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61960394/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com