Array_merge versus + [duplicate] - php

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;
}

Related

Array_Search For Multiple Same Elements [duplicate]

This question already has answers here:
How to search Array for multiple values in PHP?
(6 answers)
Closed 2 years ago.
there is an array like $arr = array(1,2,3,3,3,4,5) . What if we want to get all indexes that have values 3?
i used array_search(3, $arr) but it just give back an integer and just the first index that has value '3'
how can we get an array like $indexes = array(2,3,4) that shows all indexes that have value 3?
your help will be highly appreciated
You can use array_keys with search value PHP Doc
Demo
array_keys($arr,3)
array_keys() returns the keys, numeric and string, from the array.
If a search_value is specified, then only the keys for that value are
returned. Otherwise, all the keys from the array are returned.
you can use array_keys:
foreach (array_keys($arr) as $key) if ($arr[$key] == 3) $result[] = $key;
With that solution you can create complex filters. In this case we compare every value to be the number three (=== operator). The filter returns the index, when the comparision true, else it will be dropped.
$a = [1,2,3,4,3,3,5,6];
$threes = array_filter($a, function($v, $k) {
return $v === 3 ? $k : false; },
ARRAY_FILTER_USE_BOTH
);
$threes Is an array containing all keys having the value 3.
array(3) { 2, 4, 5 }

PHP - Elegantly extract the numeric indices in array a that are not in array b (not array_diff_key)

Suppose you have two arrays $a=array('apple','banana','canaple'); and $b=array('apple');, how do you (elegantly) extract the numeric indices of elements in array a that aren't in array b? (in this case, indices: 1 and 2).
In this case, array a will always have more elements than b.
Note, this is not asking for array_diff_key, but rather the numeric indices in the array with more elements that don't exist in the array with fewer elements.
array_diff gets you half way there. Using array_keys on the diff gets you the rest of what you want.
$a = ['apple','banana','canaple'];
$b = ['apple'];
$diff = array_diff($a, $b);
$keys = array_keys($diff);
var_dump($keys); // [1, 2]
This is because array_diff returns both the element and it's key from the first array. If you wanted to write a PHP implementation of array_diff it might look something like this...
function array_diff(Array ... $arrays) {
$return = [];
$cmp = array_shift($arrays);
foreach ($cmp as $key => $value) {
foreach($arrays as $array) {
if (!in_array($value, $array)) {
$return[$key] = $value;
}
}
}
return $return;
}
This gives you an idea how you might achieve the result, but internally php implements this as a sort, because it's much faster than the aforementioned implementation.

PHP combine arrays with logical operator

Is there a way to combine boolean arrays:
$array1: ['prop1'=>T, 'prop2'=>F, 'prop3'=>T, 'prop4'=>F, 'prop5'=>T]
$array2: ['prop1'=>T, 'prop2'=>F, 'prop3'=>F, 'prop4'=>T]
Into
$array3: ['prop1'=>T, 'prop2'=>F, 'prop3'=>T, 'prop4'=>T, 'prop5'=>T]
Using the OR comparison?
I thought using $array3 = $array1 | $array2 would work but it returns a single value.
I feel like this could be a duplicate but I failed to find the same question on SO.
While each array have the same key you can use foreach loop to loop through the first array check if equally then you set the key and value to result array else if not equally then use the one with true value
$result=array();
foreach($array1 as $key=>$value){
if($array1[$key]==$array2[$key] || $array2==undefined){
$result[$key]=$value;
}
else{
$result[$key]=($array1[$key]==True)?$array1[$key] : $array2[$key];
}
}
Then loop through second array to see if the key is undefined in first to add the key value from second array
foreach($array2 as $key=>$value){
if ($array1[$key]==undefined){
$result[$key]=$value;
}
}
This is the shortest solution I can think of. And it's really not that complicated :). First we add the two arrays to make sure all keys exist in $result. Then we use the array_walk to perform the logical operation.
We need 3 arguments. The first is the $result variable we want to manipulate.
The third argument gets passed to our callback. We again use an array sum to ensure all keys are set, but this time $array2 gets the precedence.
The second is our callback. We get each value from the preliminary result by reference (&), each key by value, and our wish as a third parameter. The function itself is really simple we just set $v to whatever operation we want to implement. || for OR, && for AND or xor for XOR (but xor needs additional parentheses, see Operator precedence).
Demo
$array1 = ['prop1'=>TRUE, 'prop2'=>FALSE, 'prop3'=>TRUE, 'prop4'=>TRUE];
$array2 = ['prop1'=>TRUE, 'prop2'=>TRUE, 'prop3'=>FALSE, 'prop5'=>FALSE];
$result = $array1 + $array2;
array_walk($result, function(&$v, $k, $a){
$v = $v || $a[$k]; //Here you can change the operation
}, $array2+$array1);
var_dump($result);

array_diff Array to string conversion in error

I want calculate different two array but i get error;
Notice: Array to string conversion in x.php on line 255
And not calculate different.
Code:
$db->where('lisansID', $_POST['licence']);
$mActivation = $db->get('moduleactivation', null, 'modulID');
$aktifler = Array();
$gelenler = Array();
foreach($mActivation as $key=>$val)
{
$aktifler[] = $val;
}
foreach ($_POST['module'] as $key => $value) {
$gelenler[] = $val;
}
echo '<pre>Aktifler: ';
print_r($aktifler);
echo '</pre>';
echo '<pre> Gelenler:';
print_r($gelenler);
echo '</pre> Fark:';
///line 255:
var_dump(array_diff($aktifler, $gelenler));
array_diff can only compare strings or values that can be casted to (string). But the elements of $aktifler and $gelenler are arrays by themselves, that's why you get this notice (also, converting an array to string always results in the string "Array", so all arrays will be treated as equal).
See array_diff:
Note:
Two elements are considered equal if and only if (string) $elem1 === (string) $elem2. In words: when the string representation is the same.
Use array_udiff instead, where you can define your own comparison function.
$out = array_udiff($aktifler, $gelenler, function($a, $b) {
// the callback must return 0 for equal values
return intval($a != $b);
});
Try breaking the final part into steps.
Take the row,
Save the output,
display the output.
thus:
$out = array_diff($aktifler, $gelenler);
var_dump($out);
You have a typo in your code, on the second foreach the $value is not assigned to the array, which is instead given $val. That's your problem.
Also you should get into the habit of unset()ing values from the foreach loop once the loop has completed.
foreach($a as $b => $c){
...
}
unset($b,$c);

PHP: How to compare keys in one array with values in another, and return matches?

I have the following two arrays:
$array_one = array('colorZero'=>'black', 'colorOne'=>'red', 'colorTwo'=>'green', 'colorThree'=>'blue', 'colorFour'=>'purple', 'colorFive'=>'golden');
$array_two = array('colorOne', 'colorTwo', 'colorThree');
I want an array from $array_one which only contains the key-value pairs whose keys are members of $array_two (either by making a new array or removing the rest of the elements from $array_one)
How can I do that?
I looked into array_diff and array_intersect, but they compare values with values, and not the values of one array with the keys of the other.
As of PHP 5.1 there is array_intersect_key (manual).
Just flip the second array from key=>value to value=>key with array_flip() and then compare keys.
So to compare OP's arrays, this would do:
$result = array_intersect_key( $array_one , array_flip( $array_two ) );
No need for any looping the arrays at all.
Update
Check out the answer from Michel: https://stackoverflow.com/a/30841097/2879722. It's a better and easier solution.
Original Answer
If I am understanding this correctly:
Returning a new array:
$array_new = [];
foreach($array_two as $key)
{
if(array_key_exists($key, $array_one))
{
$array_new[$key] = $array_one[$key];
}
}
Stripping from $array_one:
foreach($array_one as $key => $val)
{
if(array_search($key, $array_two) === false)
{
unset($array_one[$key]);
}
}
Tell me if it works:
for($i=0;$i<count($array_two);$i++){
if($array_two[$i]==key($array_one)){
$array_final[$array_two[$i]]=$array_one[$array_two[$i]];
next($array_one);
}
}

Categories