簡體   English   中英

對數據行進行分組,在組內維護一個id的子數組,只呈現每組中最低的id作為第一級key

[英]Group rows of data, maintain a subarray of ids within the group, and only present the lowest id in each group as the first level key

我需要將一組行合並到組中,並使用每個組中的最低 id 作為第一級鍵。 在每個組中,所有遇到的 id(不包括最低的)都應收集在一個名為mergedWith的子數組中。

樣本輸入:

[
    1649 => ["firstName" => "jack", "lastName" => "straw"],
    1650 => ["firstName" => "jack", "lastName" => "straw"],
    1651 => ["firstName" => "jack", "lastName" => "straw"],
    1652 => ["firstName" => "jack", "lastName" => "straw"],
]

我想要的結果:

[
    1649 => [
        "firstName" => "jack"
        "lastName" => "straw"
        "mergedWith" => [1650, 1651, 1652]
    ]
]

我有一個循環運行,可以提取重復項並找到組中最低的 ID,但不確定將它們合並為一個的正確方法。

我已經顯示了搜索的所需結果,該搜索已在這些特定字段中識別出具有重復條目的 id。 我只是想進一步完善它以不刪除,而是在每個組的末尾添加一個字段,上面寫着["mergedWith" => [1650, 1651, 1652]]

一種方法是按名字和姓氏分組,然后反轉分組以獲得單個ID。 事先krsort輸入,以確保您獲得最低的ID。

krsort($input);

//group
foreach ($input as $id => $person) {
    // overwrite the id each time, but since the input is sorted by id in descending order,
    // the last one will be the lowest id
    $names[$person['lastName']][$person['firstName']] = $id;
}

// ungroup to get the result
foreach ($names as $lastName => $firstNames) {
    foreach ($firstNames as $firstName => $id) {
        $result[$id] = ['firstName' => $firstName, 'lastName' => $lastName];
    }
}

編輯:根據您更新的問題,沒有太多不同。 只保留所有ID而不是單個ID。

krsort($input);

foreach ($input as $id => $person) {
    //                   append instead of overwrite ↓ 
    $names[$person['lastName']][$person['firstName']][] = $id;
}
foreach ($names as $lastName => $firstNames) {
    foreach ($firstNames as $firstName => $ids) {
        // $ids is already in descending order based on the initial krsort
        $id = array_pop($ids);  // removes the last (lowest) id and returns it
        $result[$id] = [
            'firstName' => $firstName,
            'lastName' => $lastName,
            'merged_with' => implode(',', $ids)
        ];
    }
}
ksort($resArr);
$tempArr = array_unique($resArr, SORT_REGULAR);
foreach ($tempArr as $key => $value) {
    foreach ($resArr as $key1 => $value2) {
        if($value['firstName'] == $value2['firstName'] && $value['lastName'] == $value2['lastName']) {
            $tempArr[$key]["mergedWith"][] = $key1;
        }
    }
}
print_r($tempArr);

$resArr = array(1650 => array(
        "firstName" => "jack",
        "lastName" => "straw"
    ),1649 => array(
        "firstName" => "jack",
        "lastName" => "straw"
    )
    ,
    1651 => array(
        "firstName" => "jack",
        "lastName" => "straw"
    ),
    1652 => array(
        "firstName" => "jack",
        "lastName" => "straw"
    ),
    1653 => array(
        "firstName" => "jack1",
        "lastName" => "straw"
    ),
    1654 => array(
        "firstName" => "jack1",
        "lastName" => "straw"
));

Output
Array
(
    [1649] => Array
        (
            [firstName] => jack
            [lastName] => straw
            [mergedWith] => Array
                (
                    [0] => 1649
                    [1] => 1650
                    [2] => 1651
                    [3] => 1652
                )

        )

    [1653] => Array
        (
            [firstName] => jack1
            [lastName] => straw
            [mergedWith] => Array
                (
                    [0] => 1653
                    [1] => 1654
                )

        )

)

@Don'tPanic 的答案是使用初步循環來創建查找數組,然后使用嵌套循環來形成所需的結果。

我推薦一種沒有嵌套循環的更簡單的方法。 在第一個循環中,過度填充每組中的mergedWith元素——這將非常快,因為沒有 function 調用並且沒有條件(除了 null 合並賦值運算符??= )。 然后使用第二個循環從mergedWith子數組中提取第一個元素——這將應用最低的 id 作為第一級鍵,並確保第一級鍵不再存在於組的子數組中。

代碼:(演示

ksort($array);
$temp = [];
foreach ($array as $key => $row) {
    $compositeKey = $row['firstName'] . '-' . $row['firstName'];
    $temp[$compositeKey] ??= $row;
    $temp[$compositeKey]['mergedWith'][] = $key;
}

$result = [];
foreach ($temp as $row) {
    $result[array_shift($row['mergedWith'])] = $row;
}
var_export($result);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM