1

I have the following associative array of objects:

[
    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"
    }
]

Please, have in mind the following format is the prettified JSON string on the browser, after returning it from PHP through an echo json_encode($result)

I need to filter it based on the number property value, in order to remove all duplicates with the same value for the number property except the first one. This means that if two or more objects share the same value for number, only the first one should remain.

Given this explanation, the filtered array from the example above would result on:

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

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

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

I have made several attempts, the closest I've been is this funcion:

function array_iunique($array) {
    $lowered = array_map('strtolower', $array);
    return array_intersect_key($array, array_unique($lowered));
}
12
  • 1
    what have you tried, show us your best attempt(code), you might be closer to a solution than you think. Please read How to Ask. Commented May 2, 2021 at 8:01
  • @berend sure, I've edited with my closest attempt. Thank you. Commented May 2, 2021 at 8:03
  • stackoverflow.com/questions/25561707/… maybe this one can help you Commented May 2, 2021 at 8:08
  • 2
    Define "except the first one" (that seems a pretty important bit). Does that mean if the key number: 1 is duplicated, its duplicate shouldn't be removed? Or whichever key is at position 0 in the array? Also, what structure are you actually working with? Is that an array of arrays, objects or JSON strings? Commented May 2, 2021 at 8:10
  • 1
    Are you certain these are PHP objects? Calling strtolower on an actual object should be throwing a warning. Commented May 2, 2021 at 8:18

2 Answers 2

0

Sounds pretty straight forward to me: you iterate over the input array and accept the elements only if the output does not yet contain such a candidate...

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

The output obviously is:

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
        )
)
Sign up to request clarification or add additional context in comments.

3 Comments

I am about to try, thank you. Please have in mind I posted the prettified JSON string from the browser, after returning it through an echo json_encode($result). I have updated the question explaining this. Sorry for the mess, I am quite unexperienced on PHP
It does not matter where that array of objects comes from. I used the JSON notation only because it intuitively reflects the data you proposed in your question.
You can. The json_decode() is not part of what I suggest. It only prepares the input data for the demonstration. If you already have an array then fine, just use that. Concentrate on the middle part of my example...
0

Simple approache:

  1. Firstly, convert data from json format to array of scores using json_decode with second args true.
  2. Secondly, create three variable one for output $scores_filtered, second to keep track only unique numbers and $index to keep the order ascending of $scores_filtered array.
  3. Thirdly, iterate over the array of score and check if the number first time occures (meaning doesn't exist in array $unique_numbers) if So, store it in $unique_numbers. get that score and store in $scores_filtered array.
$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;
    }
}

Output:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.