-3

I have an array whose values are all arrays of a specific format that looks like this:

Array
(
    [0] => Array
        (
            [0] => '8227'
            [1] => ' 8138'
        )

    [1] => Array
        (
            [0] => '8227'
            [1] => ' 8138'
            [2] => ' 7785'
        )

)

and I would like to have this:

Array
(
    [0] => 8227
    [1] => 8138
    [2] => 7785
)

How can I do this ?

0

5 Answers 5

5
$result = array();
foreach ($input as $sub) { // Loop outer array
  foreach ($sub as $val) { // Loop inner arrays
    $val = trim($val);
    if (!in_array($val, $result)) { // Check for duplicates
      $result[] = $val; // Add to result array
    }
  }
}
3
  • 1
    @ajreal Doesn't work for this particular task, just spits aout exactly what you put in. Commented Sep 12, 2011 at 11:41
  • Huh ? array_mege_recursive($array[0], $array[1] ...) ? Commented Sep 12, 2011 at 11:52
  • @ajreal Doesn't remove duplicates (although you could call array_unique() afterwards), resulting keys may be non-contiguous from the array_unique() call (although you can pass it through array_merge()) but more to the point would only work if you knew exactly how many sub arrays are in the container array. If you do all the above, takes about 50% longer than the looping approach (tested on PHP/5.2.19 on win32 over 10000 iterations). Commented Sep 12, 2011 at 12:00
3
$result = array();
foreach($array as $arr){
    $result = array_merge($result, $arr);
}

$result = array_unique($result);
3
  • +1. I like this, it's neater than mine, but is actually nearly twice as slow over 10000 iterations. This actually surprises me - I thought this would be faster - but there it is. Commented Sep 12, 2011 at 11:46
  • if there is space in the beginning of the id's it returns duplicate values.. Is it possible to overcome it... for example if there is space in id 8227 it returns twice by using the above code.. is there any way to resolve ? Commented Sep 12, 2011 at 11:50
  • @Fero I have modified my answer so it strips leading/trailing whitespace from ID's and wont cause duplicates. However, if the whitespace is in the middle of the string you would probably be best using preg_replace() to get rid of it. Commented Sep 12, 2011 at 12:04
2

array_merge_recursive() can be used to flatten the array. Then, array_unique() to get the unique values, with array_values() to "reindex" the resultant array.

$flat = call_user_func_array('array_merge_recursive', $subject);
$uniq = array_values(array_unique($flat));
0
<?php
$array = array(
0 => array(
    0 => 8227,
    1 => 8138
),
1 => array(
    0 => 8227,
    1 => 8138,
    2 => 7785
)
);

$newArray = array();
array_walk_recursive($array, function($item, $key) use(&$newArray) {
if(!in_array($item, $newArray)) {
    $newArray[] = $item;
}
});

print_r($newArray);
?>    
0

I don't like the idea of iterated calls of in_array() since it can cause a bit of drag on big arrays.

Now, my methods to follow are probably not going to set any speed records (I didn't bother to benchmark), but I thought I would post a couple of unorthodox approaches in case they may inspire future readers.

Method #1:

  • convert the multi-dimensional array to a json string
  • split the string on all non-digital substrings (this also trims the values)
  • eliminate duplicates using array_flip()
  • re-index the resultant array using array_keys() (output values are integer-type)

Method #2:

  • convert the multi-dimensional array to a json string
  • extract the words (which in this case include numbers and there aren't any letters to worry about)
  • eliminate duplicates using array_flip()
  • reindex the resultant array using array_keys() (output values are integer-type)

Code: (Demo)

$array = [['8227', '8138'], [' 8227', ' 8138', ' 7785']];

echo "regex method: ";

var_export(
    array_keys(
        array_flip(
            preg_split(
                '/\D+/',
                json_encode($array),
                0,
                PREG_SPLIT_NO_EMPTY
            )
        )
    )
);

echo "\n\nnon-regex method: ";

var_export(
    array_keys(
        array_flip(
            str_word_count(
                json_encode($array),
                1,
                '0..9'
            )
        )
    )
);

Output:

regex method: array (
  0 => 8227,
  1 => 8138,
  2 => 7785,
)

non-regex method: array (
  0 => 8227,
  1 => 8138,
  2 => 7785,
)

If either of these methods perform well, it will be because they don't make iterated function calls.

p.s. Okay, because I was curious, I just did a very small / unofficial speed test on my two methods and DaveRandom's method (only 1000 iterations using the OP's data - I didn't want to abuse 3v4l.org) and...

  • Method #1 ran about as fast as Method #2
  • Both Method #1 and Method #2 ran faster than DaveRandom's method.

Again, I'll state that fabricated tests for micro-optimization may be pointless and real tests should be done on your REAL data IF it is actually important. If you merely prefer the logical flow of another answer on this page, I totally respect that.

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.