How to convert a 2-dim array of strings into 1-dim array of trimmed, unique values?
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'
开发者_StackOverflow [2] => ' 7785'
)
)
and I would like to have this:
Array
(
[0] => 8227
[1] => 8138
[2] => 7785
)
How can I do this ?
$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
}
}
}
$result = array();
foreach($array as $arr){
$result = array_merge($result, $arr);
}
$result = array_unique($result);
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));
<?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);
?>
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.
精彩评论