3 回答

TA貢獻1844條經(jīng)驗 獲得超8個贊
雖然沒有內(nèi)置的東西可以直接開箱即用,但也不需要大量代碼來處理任意數(shù)量的屬性以考慮唯一性。通過跟蹤查找數(shù)組中的每個唯一屬性,我們可以構(gòu)建一個數(shù)組,其中葉節(jié)點(即那些本身不是數(shù)組的節(jié)點)是對象。
為此,我們&在數(shù)組中保留對當前級別的引用 ( ),然后繼續(xù)為每個屬性構(gòu)建我們的查找數(shù)組。
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;
}
使用上面的數(shù)據(jù)調(diào)用,并且要求是唯一的并且返回重復項的最后一個元素,我們得到以下結(jié)果:
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)
}
}
在您的示例中映射到 element[0]和 element [2]。如果您想要保留第一個對象以備重復,請?zhí)砑右粋€ isset 以在屬性值已被看到時終止內(nèi)部循環(huán):
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];
}
重要的是要注意,這是在假設您要檢查唯一性的數(shù)組本身不包含數(shù)組的情況下編寫的(因為我們正在查找屬性,并且因為我們正在使用查找->任何array_walk_recursive不是大批)。

TA貢獻1805條經(jīng)驗 獲得超10個贊
這很有趣:
array_multisort(array_column($animArray, 'timestamp'), SORT_DESC, $animArray);
$result = array_intersect_key($animArray,
array_unique(array_map(function($v) { return $v->dp.'-'.$v->cg; }, $animArray)));
首先,提取timestamp并對該數(shù)組進行降序排序,從而對原始數(shù)組進行排序。
dp然后,映射以使用和組合創(chuàng)建一個新數(shù)組cg。
接下來,使組合數(shù)組唯一,這將保留遇到的第一個重復項(這就是我們降序排序的原因)。
最后,得到原始數(shù)組的鍵和唯一鍵的交集。
在具有動態(tài)屬性的函數(shù)中:
function array_unique_custom($array, $props) {
array_multisort(array_column($array, 'timestamp'), SORT_DESC, $array);
$result = array_intersect_key($array,
array_unique(array_map(function($v) use ($props) {
return implode('-', array_map(function($p) use($v) { return $v->$p; }, $props));;
},
$array)));
return $result;
}
$result = array_unique_custom($animArray, ['dp', 'cg']);
另一種選擇是將其升序排序,然后構(gòu)建一個以 adp和cg組合為鍵的數(shù)組,這將保留最后一個副本:
array_multisort(array_column($animArray, 'timestamp'), SORT_ASC, $animArray);
foreach($animArray as $v) {
$result[$v->dp.'-'.$v->cg] = $v;
}
在具有動態(tài)屬性的函數(shù)中:
function array_unique_custom($array, $props) {
array_multisort(array_column($array, 'timestamp'), SORT_ASC, $array);
foreach($array as $v) {
$key = implode(array_map(function($p) use($v) { return $v->$p; }, $props));
$result[$key] = $v;
}
return $result;
}
$result = array_unique_custom($animArray, ['dp', 'cg']);

TA貢獻1829條經(jīng)驗 獲得超4個贊
//Create an array with dp and cg values only
$new_arr = [];
foreach($animArray as $key=>$item) {
$new_arr[] = $item->dp.','.$item->cg;
}
$cvs = array_count_values($new_arr);
$final_array = [];
foreach($cvs as $cvs_key=>$occurences) {
if ($occurences == 1) {
$filter_key = array_keys($new_arr, $cvs_key)[0];
$final_array[$filter_key] = $animArray[$filter_key];
}
}
最終結(jié)果將是(根據(jù)您的示例)$final_array:
[0] => anim Object
(
[qs] => fred
[dp] => shorts
[cg] => dino
[timestamp] => 1590157029399
)
一些解釋:
//Create a new array based on your array of objects with the attributes dp and cg
//with a comma between them
$new_arr = [];
foreach($animArray as $key=>$item) {
$new_arr[] = $item->dp.','.$item->cg;
}
/*
$new_arr now contains:
[0] => shorts,dino
[1] => tshirt,bird
[2] => tshirt,bird
*/
//Use builtin-function array_count_values to get the nr of occurences for
//each item in an array
$cvs = array_count_values($new_arr);
/*
$cvs would contain:
(
[shorts,dino] => 1
[tshirt,bird] => 2
)
*/
//Iterate through the $cvs array.
//Where there are only one occurence (no duplicates)
//create a final array $final_array
$final_array = [];
foreach($cvs as $cvs_key=>$occurences) {
if ($occurences == 1) {
/*
array_keys with second argument $csv_key searches for key with
with the key from $cvs-key
so basically search for:
shorts,dino and retrieve the key 0 (first element)
*/
$filter_key = array_keys($new_arr, $cvs_key)[0];
/*
Add a new item to the $final_array based on the key in
the original array $animArray
if you don't want the original key in the new array
you could just do $final_array[] instead of
$final_array[$filter_key]
*/
$final_array[$filter_key] = $animArray[$filter_key];
}
}
你說你想要某種功能測試不同的屬性。我相信它只是制作一個函數(shù)/方法,您將兩個值傳遞給參數(shù)$attr1 ('dp'?), $attr2('cg'?)或類似的東西。
更新
我沒有意識到你也想要最后一個值。這實際上似乎是一項更容易的任務。也許我遺漏了一些東西,但是想出一種與其他答案不同的方法很有趣 :-)
//Create an array with dp and cg values only
$new_arr = [];
foreach($animArray as $key=>$item) {
$new_arr[] = $item->dp.','.$item->cg;
}
//Sort keys descending order
krsort($new_arr);
//Because of sending order of keys above, the unique values would return the
//last item of the duplicates
$new_arr2 = array_unique($new_arr);
//Switch order of keys back to normal (ascending)
ksort($new_arr2);
//Create a new array based on the keys set in $new_arr2
//
$final_arr = [];
foreach($new_arr2 as $key=>$item) {
$final_arr[] = $animArray[$key];
}
的輸出$final_arr[]將是(在你的例子中)
Array
(
[0] => anim Object
(
[qs] => fred
[dp] => shorts
[cg] => dino
[timestamp] => 1590157029399
)
[1] => anim Object
(
[qs] => fred
[dp] => tshirt
[cg] => bird
[timestamp] => 1590117032286
)
)
- 3 回答
- 0 關注
- 267 瀏覽
添加回答
舉報