对象数组的唯一数组,具有对象中某些键的排除选项
Array Unique for Array of Objects with exclude option for certain keys in Object
我有一个只有几个字段的对象数组。
我能够使用以下代码获得此对象数组的唯一数组:
$aa = array_unique($dd,SORT_REGULAR);
但我想要实现的是,我想从 "unique check" 中排除对象中的某些键。假设所有对象值都匹配,除了 "valid_from" 和 "valid_to" 日期字段。
下面是数组结构:
Array
(
[9948] => stdClass Object
(
[payrate] => 78.00000
[valid_from] => 03/01/2017
[valid_to] => 03/31/2017
)
[15133] => stdClass Object
(
[payrate] => 78.00000
[valid_from] => 04/01/2017
[valid_to] => 04/31/2017
)
)
所以根据上述情况,因为我的工资率在两个对象中是相同的,但由于有效期和有效期不同,它仍将被视为不同的条目。
我们是否可以为对象数组的唯一数组指定排除某些字段。
您可以使用 array_filter
和自定义回调来过滤掉数组中的一些元素。
您所要做的就是实现您的过滤器逻辑。这里有一个简单的例子:
<?php
$array = json_decode(
'[{"name":"foo","count":2},{"name":"foo","count":10},{"name":"baz","count":5},{"name":"foobar","count":10}]'
);
$uniqueCheck = [];
$filtered = array_filter(
$array,
function ($element) use (&$uniqueCheck) {
if (isset($uniqueCheck[$element->name])) {
return false;
}
$uniqueCheck[$element->name] = true;
return true;
}
);
print_r($array);
print_r($filtered);
这将产生:
Array
(
[0] => stdClass Object
(
[name] => foo
[count] => 2
)
[1] => stdClass Object
(
[name] => foo
[count] => 10
)
[2] => stdClass Object
(
[name] => baz
[count] => 5
)
[3] => stdClass Object
(
[name] => foobar
[count] => 10
)
)
Array
(
[0] => stdClass Object
(
[name] => foo
[count] => 2
)
[2] => stdClass Object
(
[name] => baz
[count] => 5
)
[3] => stdClass Object
(
[name] => foobar
[count] => 10
)
)
编辑: 将基于 $element->count
的检查更改为 "unique $element->name
check"。
另见 array_unique for objects?
如果您使用非 stdClass 对象,您可以实现 __toString 以使用 array_unique 进行过滤。
要过滤唯一的 stdClass,仅使用少数属性,您可以尝试类似的操作:
从 PHP 7 开始,您可以使用 array_column 从 stdClass 获取值,因此如果您使用 PHP7:
array_unique(array_column($array,'payrate'));
在 PHP 7 之前你可以尝试:
array_unique(array_map(function($item) {return $item->payrate;},$array);
如果要比较的属性较多,则有不同的方法。 array_reduce
只是其中之一。
这一次的结果不会有任何重复。因此,如果所有属性都匹配,则该项目将被过滤。
$attributes = ['payrate','date']
$filtered = array_reduce($array,function($carry,$item) use ($attributes) {
if(count(array_filter($attributes,function ($attribute) use ($carry, $item) {
return !in_array($item->$attribute,array_map(function($carriedItem) use ($attribute) {
return $carriedItem->$attribute;
},$carry));
}))) {
$carry[] = $item;
}
return $carry;
},[]);
见http://sandbox.onlinephpfunctions.com/code/5f8171d76362ada7e165afeaadbecffc6cdd497a
我有一个只有几个字段的对象数组。
我能够使用以下代码获得此对象数组的唯一数组:
$aa = array_unique($dd,SORT_REGULAR);
但我想要实现的是,我想从 "unique check" 中排除对象中的某些键。假设所有对象值都匹配,除了 "valid_from" 和 "valid_to" 日期字段。
下面是数组结构:
Array
(
[9948] => stdClass Object
(
[payrate] => 78.00000
[valid_from] => 03/01/2017
[valid_to] => 03/31/2017
)
[15133] => stdClass Object
(
[payrate] => 78.00000
[valid_from] => 04/01/2017
[valid_to] => 04/31/2017
)
)
所以根据上述情况,因为我的工资率在两个对象中是相同的,但由于有效期和有效期不同,它仍将被视为不同的条目。
我们是否可以为对象数组的唯一数组指定排除某些字段。
您可以使用 array_filter
和自定义回调来过滤掉数组中的一些元素。
您所要做的就是实现您的过滤器逻辑。这里有一个简单的例子:
<?php
$array = json_decode(
'[{"name":"foo","count":2},{"name":"foo","count":10},{"name":"baz","count":5},{"name":"foobar","count":10}]'
);
$uniqueCheck = [];
$filtered = array_filter(
$array,
function ($element) use (&$uniqueCheck) {
if (isset($uniqueCheck[$element->name])) {
return false;
}
$uniqueCheck[$element->name] = true;
return true;
}
);
print_r($array);
print_r($filtered);
这将产生:
Array
(
[0] => stdClass Object
(
[name] => foo
[count] => 2
)
[1] => stdClass Object
(
[name] => foo
[count] => 10
)
[2] => stdClass Object
(
[name] => baz
[count] => 5
)
[3] => stdClass Object
(
[name] => foobar
[count] => 10
)
)
Array
(
[0] => stdClass Object
(
[name] => foo
[count] => 2
)
[2] => stdClass Object
(
[name] => baz
[count] => 5
)
[3] => stdClass Object
(
[name] => foobar
[count] => 10
)
)
编辑: 将基于 $element->count
的检查更改为 "unique $element->name
check"。
另见 array_unique for objects?
如果您使用非 stdClass 对象,您可以实现 __toString 以使用 array_unique 进行过滤。
要过滤唯一的 stdClass,仅使用少数属性,您可以尝试类似的操作:
从 PHP 7 开始,您可以使用 array_column 从 stdClass 获取值,因此如果您使用 PHP7:
array_unique(array_column($array,'payrate'));
在 PHP 7 之前你可以尝试:
array_unique(array_map(function($item) {return $item->payrate;},$array);
如果要比较的属性较多,则有不同的方法。 array_reduce
只是其中之一。
这一次的结果不会有任何重复。因此,如果所有属性都匹配,则该项目将被过滤。
$attributes = ['payrate','date']
$filtered = array_reduce($array,function($carry,$item) use ($attributes) {
if(count(array_filter($attributes,function ($attribute) use ($carry, $item) {
return !in_array($item->$attribute,array_map(function($carriedItem) use ($attribute) {
return $carriedItem->$attribute;
},$carry));
}))) {
$carry[] = $item;
}
return $carry;
},[]);
见http://sandbox.onlinephpfunctions.com/code/5f8171d76362ada7e165afeaadbecffc6cdd497a