How to merge two arrays by value in PHP [duplicate] - php

This question already has answers here:
Merge two 2d arrays by shared column value
(6 answers)
PHP - Merging two arrays into one array (also Remove Duplicates)
(9 answers)
Closed 6 months ago.
This post was edited and submitted for review 6 months ago and failed to reopen the post:
Original close reason(s) were not resolved
If I have two super-simple arrays, as such:
$a = [1, 2, 3];
$b = [2, 3, 4, 5];
How do I combine them so that the result is a single array without duplicate values? i.e.,
[1, 2, 3, 4, 5];
I would have thought this could be handled with a simple function like array_merge() or array_replace(), but those operate on keys in an associative array. I need them to go by value. I don't care about the indices in the array and I can always sort it by value if I need to using one of the many sorting methods provided by PHP.
The same problem exists with Laravel's Collections: ->merge(), ->concat(), ->replace(), ->union(), etc. don't work on values at all.
It seems incredibly inefficient to me that the only way to accomplish this is to write several lines, including a foreach() loop with if() conditions inside that use in_array() to decide whether or not to add each value from the second array to the first.
Is there a better way?
Edit 09/08/2022: Although this question was initially flagged as a duplicate of another one, the accepted answer to that question never actually answered the OP's question and, by extension, my own question of how to sort by value. In addition, the accepted answer of "use array_merge_recursive()" does not, by itself, answer my question. Finally, the question in that post involves an associative array, whereas my question disregards keys entirely. Thus, the reason why I posted this question and do not consider it a duplicate.

You can use array_unique() & array_merge() to merge and remove duplicates :
$a = [1, 2, 3];
$b = [2, 3, 4, 5];
$array = array_unique(array_merge($a, $b));
// output [1,2,3,4,5]

You can use Arr::collapse to combine multiple array and use array_unique to remove duplicate and use array_values for reindexing
e.g.
make sure to include Arr helpers
use Illuminate\Support\Arr;
then
$array = Arr::collapse([ [1, 2, 3], [2, 3, 4, 5]]);
return array_values(array_unique($array ));

Type-1: (Array Merge)
$array1 = [1, 2, 3];
$array2 = [2, 3, 4];
$finalArray = array_merge($array1, $array2);
// output [1, 2, 3, 2, 3, 4]
Type-2: (Unique array after merge)
$array1 = [1, 2, 3];
$array2 = [2, 3, 4];
$finalArray = array_unique(array_merge($array1, $array2));
// output [1, 2, 3, 4]

Related

How to remove NaN from array in PHP?

How do I remove NaN values from an array in php?
$array = [1, 3, 5, 3, float(NaN), 4, float(NaN)];
$desired_result = [1, 3, 5, 3, 4];
To remove any other element, I found this solution, but I can't get it to work for NaN.
https://stackoverflow.com/a/7225113/9606753
Context: I am reading data from an rrd Database. I want to calculate the mean across several data entries, however at least one of them is float(NaN).
Use array_filter to remove NaN with is_nan function.
$array = [1, 3, 5, 3, float(NaN), 4, float(NaN)];
$filtered_array = array_filter($array, function ($element) {
return !is_nan($element);
});
Note: This will also remove numbers that are stored as strings, '21' for example would be removed.

Inserting multiple values from an array using array_unshift() method

array_unshift is using for inserting one or many values at the beginning of an array. Now I have an array-
$data = [1, 3, 4];
Another array is needed to insert at the beginning of the $data array.
$values = [5, 6];
Here I want to insert the values 5, 6 at the beginning of the $data array, and the resulting $data would be-
$data = [5, 6, 1, 3, 4];
Note: I know there is a way like array_unshift($data, ...$values); but this is working from php7.3.x AFAIK. I need to do it below php7.3.
Is there any way to do this without looping the $values array in the reverse order?
Function array_merge exists since PHP 4:
<?php
$data = [1, 3, 4];
$values = [5, 6];
$data = array_merge($values, $data);
print_r($data);
Live PHP sandbox
You should use array_merge instead of array_unshift.
$data = [1, 3, 4];
$values = [5, 6];
$result = array_merge($values, $data); // the sequence of the array inside array_merge will decide which array should be merged at the beginning.

PHP Easy way to compare two arrays: Same values, regardless of order

Just a note of previous research on SO:
search under "[php] array sort" (15,000 results)
compare two arrays where values are not in same order (does not cleanly address direct issue)
Compare two associative arrays regarding the order of keys (different issue)
At least I believe that:
Given the example:
$arr1 = [21, 23, 25];
$arr2 = [25, 21, 23];
It the easiest, nondestructive manner to compare these for equal values, regardless of order
$arr1s = $arr1;
$arr2s = $arr2;
sort($arr1s, SORT_NUMERIC);
sort($arr2s, SORT_NUMERIC);
$isSameValues = ($arr1s === $arr2s);
Or is there an easier, cleaner way to do this?
Use array_count_values, which is O(n) vs O(n log n) for sorting
$a = [1, 1, 3, 2];
$b = [1, 2, 2, 3];
var_dump (array_count_values($b) == array_count_values($a)); //false
Note: this only works with arrays where all values are strings or ints.
You were very near to the right solution!
Here is your code fixed:
$arr1 = [21, 23, 25];
$arr2 = [25, 21, 23];
$arr1s = $arr1;
$arr2s = $arr2;
sort($arr1s, SORT_NUMERIC);
sort($arr2s, SORT_NUMERIC);
$isSameValues = ($arr1 == $arr2);
See it working here: http://sandbox.onlinephpfunctions.com/code/b737d3a9cf45e077a0d1f2c0195f389b81ace4a3
If the two arrays have same keys and values, a == is enough, as shown here:

Compare two arrays, is there common elements between the two arrays?

I need to test if one element of an array is in another array.
$array_one = array("gogo", "blabla", "toto");
$array_two = array("stackov", "renaul", "toto");
I would like to know if one element of array_one is in array_two ???
How to test that? Am trying in_array but it seems to have problems.
array_intersect()
$array1 = array("gogo", "blabla", "toto");
$array2 = array("stackov","renaul","toto");
$commonElements = array_intersect($array1,$array2);
var_dump($commonElements);
Try this one:
array_intersect($array_one, $array_two);
Mark's answer should be enough for your problem.
If you ever wish to find the intersect of more than 2 arrays, use this:
$arrays = array(
array(1, 2, 3),
array(2, 4, 6),
array(2, 8, 16)
);
$intersection = call_user_func_array('array_intersect', $arrays);

Array sorting/searching technique in PHP

I have an array let say $array = array(2, 1, 8, 3, 6, 0, 10, 10)and I want to get second largest value of that array.
Which sorting/searching technique will be best & how could I use it?
I'd just remove the duplicates from your array (using array_unique) and then use rsort (which uses Quicksort) with the SORT_NUMERIC flag to sort numerically from highest to lowest:
$array = array(2, 1, 8, 3, 6, 0, 10, 10);
$unique_array = array_unique($array);
rsort($unique_array, SORT_NUMERIC);
$second_highest = $unique_array[1]; // will be 8
The PHP manual has a comparison of sorting techniques.
Something like this?
$array = array(2, 1, 8, 3, 6, 0, 10, 10);
rsort($array);
echo $array[1]; // 10
this reverse sorts the array and then outputs the second element.
Edit: if you want the second highest unique value, just add an array_unique call:
$array = array(2, 1, 8, 3, 6, 0, 10, 10);
$array = array_unique($array);
rsort($array);
echo $array[1]; // 8
you could use rsort, but it will do a lot of additional operations which are not needed (quick sort has O(logn) complexity).
It might be a lot faster if you pass the array only in one pass like this (O(n)):
$largest=$array[0];
$secondLargest=null; //none present, by default
foreach($array as $value)
if($value>$largest)
{
$secondLargest=$largest;
$largest=$value;
}
it will be significantly faster on large arrays, but it is only good when you want the first, second, maybe third largest element. In all other cases it would be more reasonable to sort the array and take the N'th largest element dynamically.

Categories