$a = array('x' => 1, 'y' => 2, 'z' => 3, 'a' => 4, 'b' => 4);
$b = array('x', 'z', 'a');
I am looking for a NATIVE PHP function that will take the 2 above arrays and return
array('x' => 1, 'z' => 3, 'a' => 4);
I do not want to use a loop.
Any help would be appreciated.
This can be solved using array_intersect_key (http://uk3.php.net/manual/en/function.array-intersect-key.php) and array_flip (http://uk3.php.net/manual/en/function.array-flip.php);
array_intersect_key($a, array_flip($b));
See this example; https://eval.in/158360
array_intersect_key($a, array_fill_keys($b, 1));
There is native function array_intersect_key which computes the intersection of several arrays using their keys as base. But your second array is a list of values which we need to be keys. So we can use function array_fill_keys which take first argument as list of keys and create an array filled with value, specified by second parameter ( we will take integer 1, for instance ):
$b = array('x', 'z', 'a');
$bValsToKeys = array_fill_keys($b, 1);
$bValsToKeys will be
Array ( [x] => 1 [z] => 1 [a] => 1 )
And then we can intersect it with $a:
$result = array_intersect_key($a, $bValsToKeys);
print_r($result);
Out:
Array ( [x] => 1 [z] => 3 [a] => 4 )
Related
I have an array of arrays:
Array (
[0] => Array (
[a] = 1,
[b] = 'ABC',
[c] = 'ABC',
[1] => Array (
[a] = 2,
[b] = 'DEF',
[c] = 'DEF',
[2] => Array (
[a] = 3,
[b] = 'JKL',
[c] = 'JKL',
How can I have my array become like this:
Array (
[0] => Array (
[b] = 'ABC',
[a] = 1,
[c] = 'ABC',
[1] => Array (
[b] = 'DEF',
[a] = 2,
[c] = 'DEF',
[2] => Array (
[b] = 'JKL',
[a] = 3,
[c] = 'JKL',
Can I sort it by string value "b" then "a" then "c" ?
Sure you can, you just need to write your own compare function for it, and combine it with uksort. In your case, you could use a function like this ($inputis your input array, $output the result ldo):
$output = array_map(uksort($input, function ($a, $b) {
if ($a === 'b') return -1;
if ($a === 'c') return 1;
if ($b === 'b') return 1;
return -1;
}
You might want to rewrite the function, but the combination of array_map and uksort should get you started. Or don't;) since keys are unique, the four if s actually do the trick.
Your task could be rephrased as "How to move an element to the first position of a subarray?"
This can be achieved without making any iterated function calls or comparisons.
Simply iterate each subarray, generate a single-element array that contains the column to be moved to the front, then use the union operator (+) to add the full subarray to it. This will quietly overwrite b with its original value, but position it before all other elements.
Code: (Demo)
$array = [
['a' => 1, 'b' => 'ABC', 'c' => 'ABC'],
['a' => 2, 'b' => 'DEF', 'c' => 'DEF'],
['a' => 3, 'b' => 'JKL', 'c' => 'JKL']
];
var_export(
array_map(function($subarray) {
return ['b' => $subarray['b']] + $subarray;
}, $array)
);
Output:
array (
0 =>
array (
'b' => 'ABC',
'a' => 1,
'c' => 'ABC',
),
1 =>
array (
'b' => 'DEF',
'a' => 2,
'c' => 'DEF',
),
2 =>
array (
'b' => 'JKL',
'a' => 3,
'c' => 'JKL',
),
)
This outcome can be produced a multitude of ways -- this is just one.
Often this technique is not necessary when displaying associative data, but we cannot see how the data is used onward.
If this data is coming from a database, the most reasonable technique would be to use SQL sorting.
The same technique in my snippet can be used to bring multiple columns to the front of the subarrays; just nominate the order in the genetated subarray before the union operator.
If you wish to move all columns to a different position or if you have numeric keys in your subarrays, don't use the union operator; return the full subarray in the desired order (in other words, completely rewrite the subarray using variables as I have done with 'key' => $variable['key'].
I have print_r result like this :
Array
(
[0] => A, B, C, D
[1] => 15,20,24,19
)
how to make them like this :
Array
(
[A] => 15
[B] => 20
[C] => 24
[D] => 19
)
Great thanks for help :)
Try this:
$a = array('A', 'B', 'C', 'D');
$b = array(15, 20, 24, 19);
$c = array();
foreach ($a as $index => $value) {
if (isset($b[$index])) {
$c[$value] = $b[$index];
}
}
var_dump($c);
You need explode() and array_combine(). Assuming your initial array, $arr:
$new_arr = array_combine(explode(', ', $arr[0]), explode(',', $arr[1]));
See demo
Try to explode() your array index by comma and combine both array with keys and values using array_combine()
$a = explode(',',$arr[0]);
$b = explode(',',$arr[1]);
$new = array_combine($a,$b);
print_r($new); //Array ( [A] => 15 [ B] => 20 [ C] => 24 [ D] => 19 )
array_combine is the way
<?php
$myArray = array(
array('A', 'B', 'C', 'D'),
array(15, 20, 24, 19)
);
$combinedArray = array_combine($myArray[0], $myArray[1]);
I have two arrays:
$a = array([0]=>1 [1]=>2 [2]=>3);
$b = array([0]=>a [1]=>b [2]=>c);
I want to merge them like
$ab=array( [a]=>array([0]=>1 [1]=>2 [2]=>3)
[b]=>array([0]=>a [1]=>b [2]=>c) );
How to do this ?
I tried array_merge() but it does not work as I want it to.
In this case you can just go:
$ab = array('a' => $a, 'b' => $b);
You can use compact() method:
$ab = compact('a', 'b');
where 'a' and 'b' will used as array keys and treated as variable names to assign values, so it will do array('a' => $a, 'b' => $b)
You've pretty much written the answer already.
$ab = array('a' => $a, 'b' => $b);
$ab = array('a' => $a, 'b' => $b);
Will result in:
$ab['a'] = array([0] => 1, [1] => 2, [2] => 3);
$ab['b'] = array([0] => a, [1] => b, [2] => c);
Or you can just do $ab = array($a, $b) if you don't want the keys (it is unclear in your question if a and b are strings or integers).
I want to sort an array in reverse order of values. I used arsort php function but the result is not good for me.
Example:
I want to sort next array:
myArray = array("d" => 1, "f" => 2, "b" => 3, "c" => 4, "e" => 2);
after using arsort php function the result is:
myArray =array ( "c" => 4, "b" => 3, "e" => 2, "f" => 2, "d" => 1 );
which it is not good because the arsort function doesn't keep initial order of elements in array.
I want the result like:
myArray =array ( "c" => 4, "b" => 3, "f" => 2, "e" => 2, "d" => 1 );
f before e order, like from original array. keys with same value to not reverse.
Thanks.
Edit:
This isn't doable with a built in function and you need to implement your own sorting solution. You can follow this question I opened to understand more.
It is a coincidence that these solutions work:
$myArray = array("d" => 1, "f" => 2, "b" => 3, "c" => 4, "e" => 2);
uasort($myArray, function($a, $b){
if($a == $b)
return 1;
else
return $b - $a;
});
print_r($myArray);
or
$myArray = array("d" => 1, "f" => 2, "b" => 3, "c" => 4, "e" => 2);
uasort($myArray, function($a, $b){
return $a <= $b;
});
print_r($myArray);
This worked for me.
Since the asort and arsort functions seem to sort rows with equal values by descending key value, an arsort will "switch" a lower key value with a higher if the values are equal.
My solution was to sort low to high (asort), which still does the unwanted row flipping, and then reverse the array which moves the rows with identical values back into their correct respective positions.
orig: Array ( [0] => 1 [1] => 0.5 [2] => 2 [3] => 3 [4] => 0.5 )
sorted: Array ( [4] => 0.5 [1] => 0.5 [0] => 1 [2] => 2 [3] => 3 ) - notice the key values were flipped for the identical valued rows
reversed: Array ( [3] => 3 [2] => 2 [0] => 1 [1] => 0.5 [4] => 0.5 ) - now you have reverse sorted the array and kept key integrity for rows with equal values.
$array=array(1,.5,2,3,.5);
asort($array);
$array=array_reverse($array,TRUE);
Please try this
arsort($array, krsort($array));
I think that your best bet will be to use uasort php function.
The advantage of using uasort in your case it will be that you have the change to define your own sort algorithm and not be tie to php asort comparison method.
You must define a callback function to evaluate if the first value is less than, greater than or equal to the second value.
You must check the php official online documentation to understand what this function does but I think quite easy to grasp so I will leave my own solution to your problem.
function cmp($a, $b) {
if ($a == $b) {
return 0;
}
return ($a < $b) ? 1 : -1;
}
With this callback function you do a reverse sort while keeping the original order of the keys when they have the same value.
Best,
Demian
An easy, anywhere applicable way is:
<?php $a = array_flip($a); ksort($a); $a = array_flip($a); ?>
Array_flip flips each key <==> value.
Sort the array by the "now-keys";
Array_flip again to get the former constellation and a by-value sorted array.
-- P.s.: --
Why being so complicated? #others.
It seems that no response is correct for the next array:
$myArray = array(
"d" => 1, "Mircea Anca" => 2,
"b" => 3, "Iuliana Moise" => 2,
"c" => 4, "Florina Popescu" => 2 )
How can I merge two arrays (one with string => value pairs and another with int => value pairs) while keeping the string/int keys? None of them will ever overlap (because one has only strings and the other has only integers).
Here is my current code (which doesn't work, because array_merge is re-indexing the array with integer keys):
// get all id vars by combining the static and dynamic
$staticIdentifications = array(
Users::userID => "USERID",
Users::username => "USERNAME"
);
// get the dynamic vars, formatted: varID => varName
$companyVarIdentifications = CompanyVars::getIdentificationVarsFriendly($_SESSION['companyID']);
// merge the static and dynamic vars (*** BUT KEEP THE INT INDICES ***)
$idVars = array_merge($staticIdentifications, $companyVarIdentifications);
You can simply 'add' the arrays:
>> $a = array(1, 2, 3);
array (
0 => 1,
1 => 2,
2 => 3,
)
>> $b = array("a" => 1, "b" => 2, "c" => 3)
array (
'a' => 1,
'b' => 2,
'c' => 3,
)
>> $a + $b
array (
0 => 1,
1 => 2,
2 => 3,
'a' => 1,
'b' => 2,
'c' => 3,
)
Considering that you have
$replaced = array('1' => 'value1', '4' => 'value4');
$replacement = array('4' => 'value2', '6' => 'value3');
Doing $merge = $replacement + $replaced; will output:
Array('4' => 'value2', '6' => 'value3', '1' => 'value1');
The first array from sum will have values in the final output.
Doing $merge = $replaced + $replacement; will output:
Array('1' => 'value1', '4' => 'value4', '6' => 'value3');
I just want to add another possibility of doing a merge while keeping keys.
Besides adding key/values to existing arrays using the + sign you could do an array_replace.
$a = array('foo' => 'bar', 'some' => 'string', 'me' => 'is original');
$b = array(42 => 'answer to the life and everything', 1337 => 'leet', 'me' => 'is overridden');
$merged = array_replace($a, $b);
The result will be:
Array
(
[foo] => bar
[some] => string
[me] => is overridden
[42] => answer to the life and everything
[1337] => leet
)
Same keys will be overwritten by the latter array.
There is also an array_replace_recursive, which do this for subarrays, too.
Live example on 3v4l.org
Two arrays can be easily added or union without chaning their original indexing by + operator. This will be very help full in laravel and codeigniter select dropdown.
$empty_option = array(
''=>'Select Option'
);
$option_list = array(
1=>'Red',
2=>'White',
3=>'Green',
);
$arr_option = $empty_option + $option_list;
Output will be :
$arr_option = array(
''=>'Select Option'
1=>'Red',
2=>'White',
3=>'Green',
);
The OP.'s requirement is to preserve keys (keep keys) and not overlap (I think overwrite). In some cases such as numeric keys it is possible but if string keys it seems to be not possible.
If you use array_merge() the numeric keys will always re-index or renumbered.
If you use array_replace(), array_replace_recursive() it will be overlap or overwrite from the right to the left. The value with the same key on first array will be replaced with second array.
If you use $array1 + $array2 as the comment was mentioned, if the keys are same then it will keep the value from first array but drop the second array.
Custom function.
Here is my function that I just wrote to work on the same requirements. You are free to use for any purpose.
/**
* Array custom merge. Preserve indexed array key (numbers) but overwrite string key (same as PHP's `array_merge()` function).
*
* If the another array key is string, it will be overwrite the first array.<br>
* If the another array key is integer, it will be add to first array depend on duplicated key or not.
* If it is not duplicate key with the first, the key will be preserve and add to the first array.
* If it is duplicated then it will be re-index the number append to the first array.
*
* #param array $array1 The first array is main array.
* #param array ...$arrays The another arrays to merge with the first.
* #return array Return merged array.
*/
function arrayCustomMerge(array $array1, array ...$arrays): array
{
foreach ($arrays as $additionalArray) {
foreach ($additionalArray as $key => $item) {
if (is_string($key)) {
// if associative array.
// item on the right will always overwrite on the left.
$array1[$key] = $item;
} elseif (is_int($key) && !array_key_exists($key, $array1)) {
// if key is number. this should be indexed array.
// and if array 1 is not already has this key.
// add this array with the key preserved to array 1.
$array1[$key] = $item;
} else {
// if anything else...
// get all keys from array 1 (numbers only).
$array1Keys = array_filter(array_keys($array1), 'is_int');
// next key index = get max array key number + 1.
$nextKeyIndex = (intval(max($array1Keys)) + 1);
unset($array1Keys);
// set array with the next key index.
$array1[$nextKeyIndex] = $item;
unset($nextKeyIndex);
}
}// endforeach; $additionalArray
unset($item, $key);
}// endforeach;
unset($additionalArray);
return $array1;
}// arrayCustomMerge
Testing.
<?php
$array1 = [
'cat',
'bear',
'fruitred' => 'apple',
3 => 'dog',
null => 'null',
];
$array2 = [
1 => 'polar bear',
20 => 'monkey',
'fruitred' => 'strawberry',
'fruityellow' => 'banana',
null => 'another null',
];
// require `arrayCustomMerge()` function here.
function printDebug($message)
{
echo '<pre>';
print_r($message);
echo '</pre>' . PHP_EOL;
}
echo 'array1: <br>';
printDebug($array1);
echo 'array2: <br>';
printDebug($array2);
echo PHP_EOL . '<hr>' . PHP_EOL . PHP_EOL;
echo 'arrayCustomMerge:<br>';
$merged = arrayCustomMerge($array1, $array2);
printDebug($merged);
assert($merged[0] == 'cat', 'array key 0 should be \'cat\'');
assert($merged[1] == 'bear', 'array key 1 should be \'bear\'');
assert($merged['fruitred'] == 'strawberry', 'array key \'fruitred\' should be \'strawberry\'');
assert($merged[3] == 'dog', 'array key 3 should be \'dog\'');
assert(array_search('another null', $merged) !== false, '\'another null\' should be merged.');
assert(array_search('polar bear', $merged) !== false, '\'polar bear\' should be merged.');
assert($merged[20] == 'monkey', 'array key 20 should be \'monkey\'');
assert($merged['fruityellow'] == 'banana', 'array key \'fruityellow\' should be \'banana\'');
The results.
array1:
Array
(
[0] => cat
[1] => bear
[fruitred] => apple
[3] => dog
[] => null
)
array2:
Array
(
[1] => polar bear
[20] => monkey
[fruitred] => strawberry
[fruityellow] => banana
[] => another null
)
---
arrayCustomMerge:
Array
(
[0] => cat
[1] => bear
[fruitred] => strawberry
[3] => dog
[] => another null
[4] => polar bear
[20] => monkey
[fruityellow] => banana
)
Try array_replace_recursive or array_replace functions
$a = array('userID' => 1, 'username'=> 2);
array (
userID => 1,
username => 2
)
$b = array('userID' => 1, 'companyID' => 3);
array (
'userID' => 1,
'companyID' => 3
)
$c = array_replace_recursive($a,$b);
array (
userID => 1,
username => 2,
companyID => 3
)
http://php.net/manual/en/function.array-replace-recursive.php