【问题标题】:PHP: remove from array of objects all duplicates by key, except first onePHP:从对象数组中删除所有重复项,除了第一个
【发布时间】:2021-07-24 23:48:06
【问题描述】:

我有以下关联的对象数组:

[
    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));
}

【问题讨论】:

  • 您尝试过什么,向我们展示您的最佳尝试(代码),您可能比您想象的更接近解决方案。请阅读How to Ask
  • @berend 当然,我已经用我最接近的尝试进行了编辑。谢谢。
  • stackoverflow.com/questions/25561707/…也许这个可以帮到你
  • 定义“除了第一个”(这似乎很重要)。这是否意味着如果密钥 number: 1 重复,则不应删除其重复项?或者数组中位置 0 的任何键?另外,您实际使用的是什么结构?那是数组、对象还是 JSON 字符串的数组?
  • 你确定这些是 PHP 对象吗?在实际对象上调用 strtolower 应该会引发警告。

标签: php array-filter


【解决方案1】:

对我来说听起来很简单:您迭代输入数组并仅在输出尚不包含此类候选者时才接受元素...

<?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
        )
)

【讨论】:

  • 我正要试试,谢谢。请记住,在通过 echo json_encode($result) 返回它之后,我从浏览器中发布了经过美化的 JSON 字符串。我已经更新了解释这一点的问题。对不起,我对PHP很陌生
  • 对象数组来自哪里并不重要。我使用 JSON 表示法只是因为它直观地反映了您在问题中提出的数据。
  • 你可以。 json_decode() 不是我建议的一部分。它只为演示准备输入数据。如果您已经有一个数组,那么就可以使用它。专注于我的例子的中间部分......
【解决方案2】:

简单的方法:

  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"
    }
]
*/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-23
    • 2018-07-22
    相关资源
    最近更新 更多