PHP:从对象数组中删除所有重复项,除了第一个

时间:2021-05-02 07:57:00

标签: php array-filter

我有以下对象关联数组:

[
    0: {
        "score": "value2",
        "number": "1",
        "finalScore": "-1"
    },

    1: {
        "score": "value3",
        "number": "2",
        "finalScore": "5"
    },

    2: {
        "score": "value4",
        "number": "2",
        "finalScore": "5"
    },

    3: {
        "score": "value5",
        "number": "3",
        "finalScore": "-1"
    }
]

请记住,以下格式是浏览器上经过美化处理的 JSON 字符串,通过 echo json_encode($result)

从 PHP 返回后

我需要根据 number 属性值对其进行过滤,以便删除 number 属性除了第一个之外所有具有相同值的重复项。这意味着如果两个或多个对象共享相同的 number 值,则只应保留第一个。

根据这个解释,上面例子中过滤后的数组将导致:

[
    0: {
        "score": "value2",
        "number": "1",
        "finalScore": "-1"
    },

    1: {
        "score": "value3",
        "number": "2",
        "finalScore": "5"
    },

    2: {
        "score": "value5",
        "number": "3",
        "finalScore": "-1"
    }
]

我做了几次尝试,最接近的是这个功能:

function array_iunique($array) {
    $lowered = array_map('strtolower', $array);
    return array_intersect_key($array, array_unique($lowered));
}

2 个答案:

答案 0 :(得分:0)

对我来说听起来很直接:您遍历输入数组并仅在输出尚未包含此类候选时才接受元素...

<?php
$input = json_decode(<<<EOT
[
    {
        "score": "value2",
        "number": "1",
        "finalScore": "-1"
    }, {
        "score": "value3",
        "number": "2",
        "finalScore": "5"
    }, {
        "score": "value4",
        "number": "2",
        "finalScore": "5"
    }, {
        "score": "value5",
        "number": "3",
        "finalScore": "-1"
    }
]
EOT);

$output = [];
array_walk($input, function ($entry) use (&$output) {
    if (!array_key_exists($entry->number, $output)) {
        $output[$entry->number] = $entry;
    }
}); 

print_r(array_values($output));

输出显然是:

Array
(
    [0] => stdClass Object
        (
            [score] => value2
            [number] => 1
            [finalScore] => -1
        )
    [1] => stdClass Object
        (
            [score] => value3
            [number] => 2
            [finalScore] => 5
        )
    [2] => stdClass Object
        (
            [score] => value5
            [number] => 3
            [finalScore] => -1
        )
)

答案 1 :(得分:0)

简单的方法:

  1. 首先,使用 json_decode 和第二个参数 true 将数据从 json 格式转换为分数数组。
  2. 其次,创建三个变量,第一个用于输出 $scores_filtered,第二个用于仅跟踪唯一数字,$index 用于保持 $scores_filtered 数组的升序。
  3. 第三步,遍历score数组并检查该数字是否第一次出现(意思是数组$unique_numbers中不存在),如果是,则将其存储在$unique_numbers中。获取该分数并存储在 $scores_filtered 数组中。
$json = '[{
        "score": "value2",
        "number": "1",
        "finalScore": "-1"
    },{
        "score": "value3",
        "number": "2",
        "finalScore": "5"
    },{
        "score": "value4",
        "number": "2",
        "finalScore": "5"
    },{
        "score": "value5",
        "number": "3",
        "finalScore": "-1"
    }
]';
$scores = json_decode($json, true);
$scores_filtered = [];
$unique_numbers = [];
$index = 0;
for($i = 0; $i < count($scores); $i++) {
    $score = $scores[$i];
    if(!in_array($score['number'], $unique_numbers)){
        $unique_numbers[] = $score['number'];
        $scores_filtered[$index]["score"] = $score["score"];
        $scores_filtered[$index]["number"] = $score["number"];
        $scores_filtered[$index]["finalScore"] = $score["finalScore"];
        $index += 1;
    }
}

输出:

echo "<pre>";
print_r(json_encode($scores_filtered, JSON_PRETTY_PRINT));
/*
[
    {
        "score": "value2",
        "number": "1",
        "finalScore": "-1"
    },
    {
        "score": "value3",
        "number": "2",
        "finalScore": "5"
    },
    {
        "score": "value5",
        "number": "3",
        "finalScore": "-1"
    }
]
*/