i have this two arrays:
$array1 = [
'1' => 285.52,
'2' => 427.76
];
$array2 = [
'1' => 123.44,
'2' => 48.32
];
The keys on each of them are the id for the client, the first one is the amount owed and the second one is the amount payed, i want to achieve the following:
$mergedArrays = [
'1' => [
'owed' => 285.52,
'payed' => 123.44
],
'2' => [
'owed' => 427.76,
'payed' => 48.32
]
];
I was wondering if there's a PHP function to do so, i tried with array_merge_recursive but it just makes an array with the four elements together.
Any help would be really appreciated.
you can loop in the first array and merge the second according to keys
foreach($array1 as $key => $val) {
$mergedArrays[$key] = array('owed' => $val, 'payed' => $array2[$key]);
}
sample
$array1 = [
'1' => 285.52,
'2' => 427.76
];
$array2 = [
'1' => 123.44,
'2' => 48.32
];
$final_arr = array_map(function($a1, $a2) {
return array(
'owed' => $a1,
'paid' => $a2
);
}, $array1, $array2);
$final_arr = array_combine(array_keys($array1), $final_arr);
var_dump($final_arr);
Based on the comment, it seems you're looking for built-in PHP functions to do the task for you rather than going for traditional looping. But the looping method provided by Fabio is the simplest one you could go for without any other complicated approaches. I've tried my best to provide you the solution using the core PHP functions. Hope you're happy with it!
Related
This question already has answers here:
Custom key-sort a flat associative based on another array
(16 answers)
Closed 2 years ago.
Quick question, most likely for a veteran will be easy, or maybe im asking for too much.
i have this code for laravel in php, im not fan to do a foreach, is there a better way? i guess should be an existing function that replace my values of arr to the keys match on arr2, but i dont know
Its really important not to change the order.
$arr= ['filters', 'repeat', 'via', 'type'];
$arr2= [
'filters' => 'text1',
'repeat' => 'text2',
'via' => 'text3',
'type' => 'text4',
];
foreach($arr as $k)
$res[]=$arr2[$k];
return $res;
You can do it using array_map.
$arr= ['filters', 'repeat', 'via', 'type'];
$arr2 = [
'filters' => 'text1',
'repeat' => 'text2',
'via' => 'text3',
'type' => 'text4',
];
$res = array_map(function($key) use($arr2) {
return $arr2[$key];
}, $arr);
print_r($res);
You can use Laravel's array_only helper function:
$res = array_only($arr2, $arr);
If you don't want to preserve the keys then you can use the array_values function too:
$res = array_values(array_only($arr2, $arr));
Yes, two ways:
Use array_values(), assuming the values of $arr are exactly in the same order as the keys in $arr2 and always have the same keys. I'm guessing this is not exactly what you meant, but that's what your example shows. If that's the case, then it is as simple as:
$res = array_values($arr2)
Use array_map() to map the values of one array (in this case $arr) to a new array ($res):
$mapper = function($k) use ($arr2) {
return $arr2[$k];
};
$res = array_map($mapper, $arr);
You can then also add handling of cases where $k does not exist in $arr2, e.g. return null and then use array_filter to filter out the null values;
(I did not test this code but generally, this is the approach)
You can use Collection in Laravel
$res = collect($arr)->map(function ($key) use ($arr2) {
return $arr2[$key];
})->toArray()
If you just want the array values you can use the array_values() function.
$arr2= [
'filters' => 'text1',
'repeat' => 'text2',
'via' => 'text3',
'type' => 'text4',
];
$res = array_values($arr2);
This will result in the following array:
['text1', 'text2', 'text3', 'text4']
This is an array of PHP database output:
[
[hi]=>array(
[text] => 'ok'
)
[work]=>array(
[text] => 'usa'
)
[city]=>array(
[text] => 'newyork'
)
]
How do I convert it to look like this:
[
[hi]=> 'ok'
[work]=> 'usa'
[city]=> 'newyork'
]
You just want to loop over the array and build your newly formatted array.
<?php
$arr = [
'please' => [
'text' => 'it'
],
'use' => [
'text' => 'will'
],
'google' => [
'text' => 'help'
]
];
$formattedArr = [];
foreach ($arr as $k => $v) {
$formattedArr[$k] = $v['text'];
}
Another way using some array sorting methods to get us a one liner:
$formattedArr = array_combine( array_keys($arr), array_column($arr, 'text'));
array_combine is a php function that creates a new array using an array for keys and an array for values.
Simply enough, array_keys gets - you guessed it - the keys of the array.
array_column creates an array of a selected property from an inner array, so in this case, it goes plucks the 'text' values from the inner arrays.
How to get column from a multidimensional with nested key
I have an array which is multidimensional. I have to pull a key as column but it is nested. like object accessing how to achieve this with minimum line of code or optimized.
Array
$array = [
[
'price' => [
'cost' => 200, 'tax' => 10, 'total' => 210
],
'otherKey' => 'etc'
],
[
'price' => [
'cost' => 500, 'tax' => 50, 'total' => 550
],
'otherKey' => 'etc'
],
[
'price' => [
'cost' => 600, 'tax' => 60, 'total' => 660
],
'otherKey' => 'etc'
],
];
becuase this can be done by using foreach, array_map() and array_column()
I have done it.
using array_column()
$result = array_column(array_column($array, 'price'), 'total');
printf($result);
in above i have to use array_column() two time that i don't want to use
using foreach
$result = [];
foreach ($array as $value) {
$result[] = $value['price']['total'];
}
printf($result);
this is working good but is there any better way.
is there any way that i can specify nested key in array_column() like
array_column($array, 'price.total'); // something like this
Result
array: [
0 => 210
1 => 550
2 => 660
]
i have searched but unable to find any question like this that's way i asked.
Thanks in Advance.
foreach is better way to do that even you can do a benchmark for performance you can have idea.
The simple foreach should do the job, you could also write a function which takes a string as input, splits it and retrieves the values from the array.
Another option which may be more ideal if:
the array structure gets a little too convoluted AND
as long as the key that you are trying to access is unique to the values that you are trying to target
is to use array_walk_recursive(). It will only visit "leafnodes" so it spares you from needing to check if an element is an array or not.
When used in this fashion, the output will be a flattened array.
Code: (Demo)
$totals = [];
array_walk_recursive(
$array,
function($leafNode, $key) use(&$totals) {
if ($key === 'total') {
$totals[] = $leafNode;
}
}
);
var_export($totals);
Output:
array (
0 => 210,
1 => 550,
2 => 660,
)
So I have a result from a form post that looks like this:
$data = [
'id_1' => [
'0' => 1,
'1' => 2
],
'id_2' => [
'0' => 3,
'1' => 4
],
'id_3' => [
'0' => 5,
'1' => 6
]
];
What I want to achieve is to split this array into two different arrays like this:
$item_1 = [
'id_1' => 1,
'id_2' => 3,
'id_3' => 5
]
$item_2 = [
'id_1' => 2,
'id_2' => 4,
'id_3' => 6
]
I've tried using all of the proper array methods such as array_chunk, array_merge with loops but I can't seem to get my mind wrapped around how to achieve this. I've seen a lot of similar posts where the first keys doesn't have names like my array does (id_1, id_2, id_3). But in my case the names of the keys are crucial since they need to be set as the names of the keys in the individual arrays.
Much shorter than this will be hard to find:
$item1 = array_map('reset', $data);
$item2 = array_map('end', $data);
Explanation
array_map expects a callback function as its first argument. In the first line this is reset, so reset will be called on every element of $data, effectively taking the first element values of the sub arrays. array_map combines these results in a new array, keeping the original keys.
The second line does the same, but with the function end, which effectively grabs the last element's values of the sub-arrays.
The fact that both reset and end move the internal array pointer, is of no concern. The only thing that matters here is that they also return the value of the element where they put that pointer to.
Solution without loop and just for fun:
$result = [[], []];
$keys = array_keys($data);
array_map(function($item) use(&$result, &$keys) {
$key = array_shift($keys);
$result[0][$key] = $item[0];
$result[1][$key] = $item[1];
}, $data);
Just a normal foreach loop will do.
$item_1 = [];
$item_2 = [];
foreach ($data as $k => $v){
$item_1[$k] = $v[0];
$item_2[$k] = $v[1];
}
Hope this helps.
I have two arrays
they look like
$a1 = array(
array('num' => 1, 'name' => 'one'),
array('num' => 2, 'name' => 'two'),
array('num' => 3, 'name' => 'three'),
array('num' => 4, 'name' => 'four'),
array('num' => 5, 'name' => 'five')
)
$a2 = array(3,4,5,6,7,8);
I want to end up with an array that looks like
$a3 = array(3,4,5);
so basically where $a1[$i]['num'] is in $a2
I know I could do
$a3 = array();
foreach($a1 as $num)
if(array_search($num['num'], $a2))
$a3[] = $num['num'];
But that seems like a lot of un-needed iterations.
Is there a better way?
Ah Snap...
I just realized I asked this question the wrong way around, I want to end up with an array that looks like
$a3 array(
array('num' => 3, 'name' => 'three'),
array('num' => 4, 'name' => 'four'),
array('num' => 5, 'name' => 'five')
)
You could extract the relevant informations (the 'num' items) from $a1 :
$a1_bis = array();
foreach ($a1 as $a) {
$a1_bis[] = $a['num'];
}
And, then, use array_intersect() to find what is both in $a1_bis and $a2 :
$result = array_intersect($a1_bis, $a2);
var_dump($result);
Which would get you :
array
2 => int 3
3 => int 4
4 => int 5
With this solution :
you are going through $a1 only once
you trust PHP on using a good algorithm to find the intersection between the two arrays (and/or consider that a function developed in C will probably be faster than any equivalent you could code in pure-PHP)
EDIT after the comment : well, considering the result you want, now, I would go with another approach.
First, I would use array_flip() to flip the $a2 array, to allow faster access to its elements (accessing by key is way faster than finding a value) :
$a2_hash = array_flip($a2); // To speed things up :
// accessing by key is way faster than finding
// an item in an array by value
Then, I would use array_filter() to apply a filter to $a1, keeping the items for which num is in the $a2_hash flipped-array :
$result = array_filter($a1, function ($item) use ($a2_hash) {
if (isset($a2_hash[ $item['num'] ])) {
return true;
}
return false;
});
var_dump($result);
Note : I used an anonymous function, which only exist with PHP >= 5.3 ; if you are using PHP < 5.3, this code can be re-worked to suppress the closure.
With that, I get the array you want :
array
2 =>
array
'num' => int 3
'name' => string 'three' (length=5)
3 =>
array
'num' => int 4
'name' => string 'four' (length=4)
4 =>
array
'num' => int 5
'name' => string 'five' (length=4)
Note the keys are not corresponding to anything useful -- if you want them removed, just use the array_values() function on that $result :
$final_result = array_values($result);
But that's probably not necessary :-)