1

Sorry if this was asked before, but I searched a lot and couldn't find a solution. I've been trying to solve this problem for a while now, and couldn't write the function for it.

I have an array like that:

    $numbers = array(
        array("tag" => "developer", "group" => "grp_1", "num" => "123123"),
        array("tag" => "developer", "group" => "grp_2", "num" => "111111"),
        array("tag" => "student", "group" => "grp_1", "num" => "123123"),
        array("tag" => "student", "group" => "grp_2", "num" => "123123"),
        array("tag" => "developer", "group" => "grp_3", "num" => "111111"),
    );

I need to write a function, that removes the duplicates off this array, based on multiple keys, so my function call should look something like that:

unique_by_keys($numbers, array("num","group"));

In other terms, one number can't be in the same group more than once.

After calling unique_by_keys() by array should be like that:

    $numbers = array(
        array("tag" => "developer", "group" => "grp_1", "num" => "123123"),
        array("tag" => "developer", "group" => "grp_2", "num" => "111111"),
        array("tag" => "student", "group" => "grp_2", "num" => "123123"),
        array("tag" => "developer", "group" => "grp_3", "num" => "111111"),
    );

I'd appreciate if you could help me find a solution, or lead me to the correct way of thinking. Thanks!


SOLUTION: I was able to find a solution, by writing the following function: ( I wrote it in a way that accepts many forms of $haystack arrays )

function unique_by_keys($haystack = array(), $needles = array()) {
    if (!empty($haystack) && !empty($needles)) {
        $_result = array();
        $result = array();
        $i = 0;
        foreach ($haystack as $arrayObj) {
            if (is_array($arrayObj)) {
                $searchArray = array();
                foreach ($needles as $needle) {
                    if (isset($arrayObj[$needle])) {
                        $searchArray[$needle] = $arrayObj[$needle];
                    }
                }
                if (!in_array($searchArray, $_result)) {
                    foreach ($arrayObj as $key => $value) {
                        if (in_array($key, $needles)) {
                            $_result[$i][$key] = $value;
                        }
                    }
                    $result[] = array_merge($_result[$i], $arrayObj);
                }
            } else {
                $result[] = $arrayObj;
            }
            $i++;
        }
        return $result;
    }
}

Thanks for everyone that replied!

3 Answers 3

3

Create composite string keys which represent the targeted/filtering column values -- this will assure sufficiently unique identification while filtering.

Using the "null coalescing assignment operator" (??=) will ensure that only the first encountered qualifying row will be retained.

Code: (Demo)

function unique_by_keys(array $haystack, array $needles): array {
    $columnNames = array_flip($needles);
    $result = [];
    foreach ($haystack as $row) {
        $compositeKey = implode('|', array_intersect_key($row, $columnNames));
        $result[$compositeKey] ??= $row;
    }
    return array_values($result);
}

var_export(
    unique_by_keys($numbers, ["group", "num"])
);
Sign up to request clarification or add additional context in comments.

Comments

1
$newNumbers = array();
foreach($numbers as $key=>$values){
    $newkey = $values['group'].'__'.$values['num']; 
    $newNumbers[$newkey] = $values;
}
var_dump($newNumbers)

1 Comment

Haha, that's a hack that could work! I love your answer, gonna use this, with some minor editing to support more than two keys.
0

Code might not be efficient, but i will work for you :)

$result = unique_by_keys($numbers, array("num","group"));

echo "<pre>";
print_R($result);

function unique_by_keys($numbers, $arr){
    $new_array = array();
    $output = array();
    foreach ($numbers as $n){

        if(isset($new_array[$n[$arr[1]]]) && $new_array[$n[$arr[1]]] == $n[$arr[0]]){
            continue;
        }else{
            $new_array[$n[$arr[1]]] = $n[$arr[0]];
            $output[] = $n;
        }

    }
    return $output;
}

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.