I have two sequential (non-associative) arrays whose values I want to combine into a new array, ignoring the index but preserving the order. Is there a better solution (i.e. an existing operator or function) other than do the following:
$a = array('one', 'two');
$b = array('three', 'four', 'five');
foreach($b as $value) {
$a[] = $value;
}
Remark: The '+' operator doesn't work here ('three' with index 0 overwrites 'one' with index zero). The function array_merge has the same problem.
array_merge is what you want, and I don't think you are correct with that overwriting problem. From the manual:
If, however, the arrays contain numeric keys, the later value will not overwrite the original value, but will be appended.
$a + $b on two arrays is the union of $a and $b:
The + operator appends elements of remaining keys from the right handed array to the left handed, whereas duplicated keys are NOT overwritten.
So use array_merge to merge both arrays:
$merged = array_merge($a, $b);
Related
$a = array("a","b");
$b = array("a"=>"one", "b" => "two","c"=>"three");
I need help in finding the difference between two arrays one with key and another without key.
required output
"c"=>"three"
Use array_diff_key() and array_flip():
$difference = array_diff_key(
$b,
array_flip($a)
);
For reference, see:
http://php.net/manual/en/function.array-diff-key.php
http://php.net/manual/en/function.array-flip.php
For an example, see:
https://3v4l.org/YgNhB
Every array has keys. Even if you have not set them.
So, your arrays look like this:
$a = array(0=>"a",1=>"b");
$b = array("a"=>"one", "b" => "two","c"=>"three");
And you trying to compare the values of one array with the keys of the other.
That's why localheinz is using array_flip() in his answer.
I am using array_diff() to take values out of array1 which are found in array2. The issue is it removes all occurrences from array1, as the PHP documentations makes note of. I want it to only take out one at a time.
$array1 = array();
$array1[] = 'a';
$array1[] = 'b';
$array1[] = 'a';
$array2 = array();
$array2[] = 'a';
It should return an array with one 'a' and one 'b', instead of an array with just 'b';
Just for the fun of it, something that just came to mind. Will work as long as your arrays contain strings:
$a = array('a','b','a','c');
$b = array('a');
$counts = array_count_values($b);
$a = array_filter($a, function($o) use (&$counts) {
return empty($counts[$o]) || !$counts[$o]--;
});
It has the advantage that it only walks over each of your arrays just once.
See it in action.
How it works:
First the frequencies of each element in the second array are counted. This gives us an arrays where keys are the elements that should be removed from $a and values are the number of times that each element should be removed.
Then array_filter is used to examine the elements of $a one by one and remove those that should be removed. The filter function uses empty to return true if there is no key equal to the item being examined or if the remaining removal count for that item has reached zero; empty's behavior fits the bill perfectly.
If neither of the above holds then we want to return false and decrement the removal count by one. Using false || !$counts[$o]-- is a trick in order to be terse: it decrements the count and always evaluates to false because we know that the count was greater than zero to begin with (if it were not, || would short-circuit after evaluating empty).
Write some function that removes elements from first array one by one, something like:
function array_diff_once($array1, $array2) {
foreach($array2 as $a) {
$pos = array_search($a, $array1);
if($pos !== false) {
unset($array1[$pos]);
}
}
return $array1;
}
$a = array('a', 'b', 'a', 'c', 'a', 'b');
$b = array('a', 'b', 'c');
print_r( array_diff_once($a, $b) );
foreach ($this->getGalleryImages() as $_image){
$a=explode('/',$_image->getPath());
$b=explode('-',$a[count($a)-1]);
$colors[]=$b[1];
}
why i can't change $colors[]=$b[1]; to $colors=$b[1]; . but $color=array_unique($colors); this is ok. $color it doesn't has [] ($color[])
array_unique() returns an array, so if you assign that to another variable ($colors), that variable will be an array, too.
$b[1] gives only one element of an array - assign that to another variable and you will get a "simple" variable, not an array. to get an array in this case, you'll have to add the value as a entry to $colors (by writing [] and thus making it an array again).
$a []= $b means "append $b to the array $a".
$a = $b means "set $a to refer to $b".
To more directly answer your question, you can say $colors = $b[1], but that means "let $colors refer to the element at the index 1 in $b", and not "add the element at the index 1 in $b to the array $colors".
array_unique returns the unique values as an array. So you will be assigning the array of unique values to $colors.
This question already has answers here:
What's the difference between array_merge and array + array? [duplicate]
(9 answers)
Closed 7 years ago.
When I use array_merge() with associative arrays I get what I want, but when I use them with numerical key arrays the keys get changed.
With + the keys are preserved but it doesn't work with associative arrays.
I don't understand how this works, can anybody explain it to me?
Because both arrays are numerically-indexed, only the values in the first array will be used.
The + operator returns the right-hand array appended to the left-hand array; for keys that exist in both arrays, the elements from the left-hand array will be used, and the matching elements from the right-hand array will be ignored.
http://php.net/manual/en/language.operators.array.php
array_merge() has slightly different behavior:
If the input arrays have the same string keys, then the later value for that key will overwrite the previous one. If, however, the arrays contain numeric keys, the later value will not overwrite the original value, but will be appended. Values in the input array with numeric keys will be renumbered with incrementing keys starting from zero in the result array.
http://php.net/manual/en/function.array-merge.php
These two operation are totally different.
array plus
Array plus operation treats all array as assoc array.
When key conflict during plus, left(previous) value will be kept
null + array() will raise fatal error
array_merge()
array_merge() works different with index-array and assoc-array.
If both parameters are index-array, array_merge() concat index-array values.
If not, the index-array will to convert to values array, and then convert to assoc array.
Now it got two assoc array and merge them together, when key conflict, right(last) value will be kept.
array_merge(null, array()) returns array() and got a warning said, parameter #1 is not an array.
I post the code below to make things clear.
function array_plus($a, $b){
$results = array();
foreach($a as $k=>$v) if(!isset($results[$k]))$results[$k] = $v;
foreach($b as $k=>$v) if(!isset($results[$k]))$results[$k] = $v;
return $results;
}
//----------------------------------------------------------------
function is_index($a){
$keys = array_keys($a);
foreach($keys as $key) {
$i = intval($key);
if("$key"!="$i") return false;
}
return true;
}
function array_merge($a, $b){
if(is_index($a)) $a = array_values($a);
if(is_index($b)) $b = array_values($b);
$results = array();
if(is_index($a) and is_index($b)){
foreach($a as $v) $results[] = $v;
foreach($b as $v) $results[] = $v;
}
else{
foreach($a as $k=>$v) $results[$k] = $v;
foreach($b as $k=>$v) $results[$k] = $v;
}
return $results;
}
So far I have done the following:
$row = mysql_fetch_assoc($result);
$row2 = mysql_fetch_assoc($result);
$duplicates = array_intersect($row, $row2);
How do I combine the 2 arrays and make a new one that just contains one instance of the previously repeated variables? (so if array $row contained the variable 'apple' 2 times and the array $row2 contained the variable 'apple' 3 times, in the new, merged array, 'apple' would only appear once.
edit: I didn't realize that the array_merge() function works differently for numbers than compared to strings. I gave the 'apple' example above but my arrays are dealing with product IDs which are numbers. PHP manual says
If, however, the arrays contain numeric keys, the later value will not
overwrite the original value, but will be appended.
and I need help in merging arrays with numbers, what should I do?
You can use
$c = array_merge($a, $b);
http://php.net/manual/en/function.array-merge.php
if you want to remove duplicate values after the merge then use array_unique();
so...
$c = array_unique(array_merge($a, $b));