如何将字符串数组与数字数组进行比较?
dear users of StackOverflow. There is some problem.
Array 1:
array: 3 [▼
0 => "8"
1 => "13"
2 => "15"
]
Array 2:
array: 16 [▼
0 => 7
1 => 8
2 => 9
]
array_diff does not work, because in the first number, in the second string.
Please suggest any ideas for solving the issue. I will be happy with any comment. Many thanks.
亲爱的StackOverflow用户。 有一些问题。 p>
数组1:
array:3 [▼
0 => “8”
1 => “13”
2 => “15”
]
Array 2:
array:16 [▼
0 => 7
1 => 8
2 => 9
]
code> pre>
array_diff不起作用,因为在第一个数字中,在第二个字符串中。 p>
请提示 任何解决问题的想法。 任何评论我都会很高兴。 非常感谢。 p>
div>
You can use array_udiff
to compare the arrays using a user-defined callback which converts the values to ints before comparing:
$array1 = array('8', '13', '15');
$array2 = array(7, 8, 9);
$diffs = array_udiff($array1, $array2, function ($a, $b) { return (int)$a - (int)$b; });
print_r($diffs);
Output:
Array
(
[1] => 13
[2] => 15
)
Update
It has been pointed out that the desired output hasn't been specified, so here is how to get all unique values:
$diffs1 = array_udiff($array1, $array2, function ($a, $b) { return (int)$a - (int)$b; });
$diffs2 = array_udiff($array2, $array1, function ($a, $b) { return (int)$a - (int)$b; });
$diffs = array_merge($diffs1, $diffs2);
print_r($diffs);
Output:
Array
(
[0] => 13
[1] => 15
[2] => 7
[3] => 9
)
and all matching values using array_uintersect
:
$same = array_uintersect($array1, $array2, function ($a, $b) { return (int)$a - (int)$b; });
print_r($same);
Output:
Array
(
[0] => 8
)
Note
In PHP7 there is now the spaceship operator (<=>
) which can also be used in the comparison function e.g.
$diffs = array_udiff($array1, $array2, function ($a, $b) { return (int)$a <=> (int)$b; });
You could convert the arrays using array map like this
$a1 = array_map('intval', $a1);
$a2 = array_map('intval', $a2);
Then do your array diff and what not.
@Nick's solution is a bit more elegant.
Because, it's not walking the arrays 2x more then you really need to. Of course if you know which is string then you could just convert that one, but I thought I would post another way to do it...
For testing you can simply do this
$a = [
"1",
"2" ,
"3"
];
var_dump($a);
var_dump(array_map('intval', $a));
Output
array(3) {
[0]=> string(1) "1"
[1]=> string(1) "2"
[2]=> string(1) "3"
}
array(3) {
[0]=> int(1)
[1]=> int(2)
[2]=> int(3)
}
And this shows that it does convert the values to string, which was pretty obvious, but I like examples. So there you go.
Cheers!
UPDATE
After doing some simple bench marking, with an array of 100,000 string numbers, and taking the average time from 100 iterations, it took apx 0.0072/seconds to convert the array back to ints:
//setup
$a = array_map('strval', range(0, 100000));
//get microtime as float after setup
$time = microtime(true);
//use the average of 100 conversion for consistency
$iterations = 100;
for($i=0;$i<$iterations; ++$i){
$b = array_map('intval', $a); //set to $b so we don't convert $a on our first iteration.
//check the first iteration, to make sure we have it setup correctly for our averaging
if($i==0)
echo number_format(
((microtime(true) - $time)),
4
)." \seconds
";
}
echo number_format(
((microtime(true) - $time) / $itterations),
4
)." \seconds
";
Output
0.0067 \seconds
//if these are close (which they are) we have everything setup right,
//it's better to take the average for speed testing.
//and I just wanted to double check that it was being done correctly
0.0072 \seconds
-note- the sandbox has only 134M of Ram for PHP (i've run it out of memory on purpose to test it.. lol)
<b>Fatal error</b>: Allowed memory size of 134217728 bytes exhausted
UPDATE1
It has been pointed out that the desired output hasn't been specified, so here is how to get all unique values:
If you want the Unique values from both arrays you can do
$unique = array_unique(array_replace($a1,$a2));
And if the arrays are unique beforehand you can just do array_replace
because you will be combining 2 unique arrays replacing any in the one array that are duplicated in the other. Therefore the result will be the unique combination of 2 unique arrays, if that makes sense.