2

I have an array that looks like this

$array = array(
  array("John","Smith","1"),
  array("Bob","Barker","2"),
  array("Will","Smith","2"),
  array("Will","Smith","4")
);

In the end I want the array to look like this

$array = array(
  array("John","Smith","1"),
  array("Bob","Barker","2"),
  array("Will","Smith","2")
);

The array_unique with the SORT_REGULAR flag checks for all three value. I've seen some solutions on how to remove duplicates based on one value, but I need to compare the first two values for uniqueness.

3
  • So collect values in array and check if something is already there. Commented Mar 9, 2017 at 20:16
  • Loop and build array with the key as a concatenation of both. Commented Mar 9, 2017 at 20:18
  • Two answers keep array("Will","Smith","2") and one can keep either array("Will","Smith","2") or array("Will","Smith","4") since you didn't specify if it was important. Commented Mar 9, 2017 at 20:39

3 Answers 3

3

Simple solution using foreach loop and array_values function:

$arr = array(
          array("John","Smith","1"), array("Bob","Barker","2"), 
          array("Will","Smith","2"), array("Will","Smith","4")
);

$result = [];
foreach ($arr as $v) {
    $k = $v[0] . $v[1];  // considering first 2 values as a unique key
    if (!isset($result[$k])) $result[$k] = $v;
}

$result = array_values($result);
print_r($result);

The output:

Array
(
    [0] => Array
        (
            [0] => John
            [1] => Smith
            [2] => 1
        )

    [1] => Array
        (
            [0] => Bob
            [1] => Barker
            [2] => 2
        )

    [2] => Array
        (
            [0] => Will
            [1] => Smith
            [2] => 2
        )
)
Sign up to request clarification or add additional context in comments.

5 Comments

No need to check if key exists. Keys will be unique. If it's important that the first one be retained then loop in reverse.
@AbraCadaver, I don't think so. If I omit a key check the last value will be array("Will","Smith","4") but the OP posted an exact output with exact values where the last is array("Will","Smith","2")
Yes, that's why I said if it's important to keep the first then just array_reverse before and after.
@AbraCadaver, I can not say that array_reverse approach is quite bad. But foreach - array_values approach is over 4 times faster(tested on 1000 iterations, PHP 5.6)
@RomanPerekhrest Such a simple solutions. Can't say I would've come up with your version on my own, but now I wonder why I didn't think of merging two values and placing them into a new array and then use in_array on each loop to check for a duplicate. Thank you.
0

Sample code with comments:

// array to store already existing values
$existsing = array();
// new array
$filtered = array();

foreach ($array as $item) {
    // Unique key
    $key = $item[0] . ' ' . $item[1];

    // if key doesn't exists - add it and add item to $filtered
    if (!isset($existsing[$key])) {
        $existsing[$key] = 1;
        $filtered[] = $item;
    }
}

1 Comment

No need to check if key exists. Keys will be unique. If it's important that the first one be retained then loop in reverse.
0

For fun. This will keep the last occurrence and eliminate the others:

$array = array_combine(array_map(function($v) { return $v[0].$v[1]; }, $array), $array);
  • Map the array and build a key from the first to entries of the sub array
  • Use the returned array as keys in the new array and original as the values

If you want to keep the first occurrence then just reverse the array before and after:

$array = array_reverse($array);
$array = array_reverse(array_combine(array_map(function($v) { return $v[0].$v[1]; },
                                               $array), $array));

4 Comments

can the OP obtain array("Will","Smith","2") as the last value with this solution?
@RomanPerekhrest Yes, the second example does that since they didn't specify.
seems like this code will perform poorly given larger data sets.
You can benchmark it. It's ugly too. The other answers are better.

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.