Merge two array into one with the same key - php

I am trying to merge two array with the same key into one.
After i dump these variables
var_dump($allArtistsName);
var_dump($allTracksName);
I get this output
First array
array (size=3749)
0 => string 'Avicii' (length=6)
1 => string 'Arctic Monkeys' (length=14)
2 => string 'DJ Antoine' (length=10)
and second array
array (size=2135)
0 => string 'Hey Brother' (length=11)
1 => string 'Do I Wanna Know?' (length=16)
2 => string 'House Party - Airplay Edit' (length=26)
Basicly key 0 from first array matches with key 0 from second array.
So i am tryin go merge them somehow.
I have tried aarray_merge and array_merge_recursive
but i does not seem to work.
How i can solve this the best ?
EDIT:
My expected output would be something like
[
0 => [
'track' => 'Hey Brother',
'artists' => Avicii
1 => [
'track' => 'x',
'artists' => y
]

Several options:
$a = ['Avicii', 'Arctic Monkeys', 'DJ Antoine'];
$t = ['Hey Brother', 'Do I Wanna Know?', 'House Party - Airplay Edit'];
// option 1 - artist name as key, track as value
print_r(array_combine($a, $t));
// option 2 - artist name and track as subarray
print_r(array_map(null, $a, $t));
// option 3 - your expected output
$newArray = [];
foreach ($a as $key => $v) {
$newArray[] = [
'artist' => $v,
'track' => $t[$key],
];
}

You can use array_map thingie with a callback:
<?php
$artists = [
'Avicii',
'Arctic Monkeys',
'DJ Antoine',
];
$tracks = [
'Hey Brother',
'Do I Wanna Know?',
'House Party - Airplay Edit',
];
$merged = array_map(
function ($artist, $track) {
return ['artist' => $artist, 'track' => $track];
},
$artists,
$tracks
);
print_r($merged);
Output will be:
Array
(
[0] => Array
(
[artist] => Avicii
[track] => Hey Brother
)
[1] => Array
(
[artist] => Arctic Monkeys
[track] => Do I Wanna Know?
)
[2] => Array
(
[artist] => DJ Antoine
[track] => House Party - Airplay Edit
)
)

Related

slice and merge 2 arrays

is there a good way to slice and merge 2 arrays based on empty values for example
first array
0 => string 'Perfect all gorgeous and arrived in less than 1 month for brazil' (length=64)
1 => string '' (length=0)
2 => string '' (length=0)
3 => string 'Good figures for their money, only instead of bits normal stick child bit rastroilsya' (length=85)
4 => string '' (length=0)
5 => string '' (length=0)
second array
0 => string '' (length=0)
1 => string 'http://g01.a.alicdn.com/kf/UTB8jjnecFfFXKJk43Otq6xIPFXaw.jpg" data-eid="eid-201782563197' (length=88)
2 => string 'http://g01.a.alicdn.com/kf/UTB87.bdcNHEXKJk43Jeq6yeeXXaZ.jpg" data-eid="eid-201782563197' (length=88)
3 => string '' (length=0)
4 => string 'http://g01.a.alicdn.com/kf/UTB8cxXwg4HEXKJk43Jeq6yeeXXam.jpg" data-eid="eid-201833045441' (length=88)
5 => string 'http://g04.a.alicdn.com/kf/UTB824Xwg4HEXKJk43Jeq6yeeXXaB.jpg" data-eid="eid-201833045441' (length=88)
I want them to be like this array
array (size=2)
0 =>
array (size=2)
'comment' => string 'Perfect all gorgeous and arrived in less than 1 month for brazil' (length=64)
'images' =>
array (size=2)
0 => string 'http://g01.a.alicdn.com/kf/UTB8jjnecFfFXKJk43Otq6xIPFXaw.jpg" data-eid="eid-201782563197' (length=88)
1 => string 'http://g01.a.alicdn.com/kf/UTB87.bdcNHEXKJk43Jeq6yeeXXaZ.jpg" data-eid="eid-201782563197' (length=88)
1 =>
array (size=2)
'comment' => string 'Good figures for their money, only instead of bits normal stick child bit rastroilsya' (length=85)
'images' =>
array (size=2)
3 => string 'http://g01.a.alicdn.com/kf/UTB8cxXwg4HEXKJk43Jeq6yeeXXam.jpg" data-eid="eid-201833045441' (length=88)
4 => string 'http://g04.a.alicdn.com/kf/UTB824Xwg4HEXKJk43Jeq6yeeXXaB.jpg" data-eid="eid-201833045441' (length=88)
How to do it ?
Got something that will help. It will work with more inputs if you need. It might not work best if your second array has more than one breaking blank. Just working on updated code to solve such issues.
<?php
$arr1 = array("input", "", "", "another input", "", "", "yet another input", "");
$arr2 = array("", "p1", "p2", "", "p01", "p02", "","p11" );
$inp = array("comment" => $arr1, "images" => $arr2);
function mangle_arrays($input) {
$out = array();
$gen = 0;
foreach($input as $key=>$val) {
$id = $gen?-1:0;
if ($gen) {
foreach($val as $v) {
if ($v) {
$out[$id][$key][] = $v;
} else {
$id++;
}
}
} else {
foreach($val as $v) {
if ($v) {
$out[$id] = array();
$out[$id][$key] = $v;
$id++;
}
}
}
$gen++;
}
return $out;
}
// your code goes here
echo "<pre>";
print_r(mangle_arrays($inp));
Results
Array
(
[0] => Array
(
[comment] => input
[images] => Array
(
[0] => p1
[1] => p2
)
)
[1] => Array
(
[comment] => another input
[images] => Array
(
[0] => p01
[1] => p02
)
)
[2] => Array
(
[comment] => yet another input
[images] => Array
(
[0] => p11
)
)
)

PHP Apply multiple callback functions when using array_map, array_walk etc. functions

I have encountered an array of serialized values like below:
Array
(
[primary] => Array
(
[key_type_0_key_name] => a:1:{i:0;s:5:"27232";}
[key_type_1_key_name] => a:1:{i:0;s:5:"27231";}
[key_type_2_key_name] => a:1:{i:0;s:5:"27147";}
[key_type_3_key_name] => a:1:{i:0;s:5:"27157";}
)
[additional] => Array
(
[key_type_0_key_othername] => a:1:{i:0;s:5:"27169";}
[key_type_1_key_othername] => a:1:{i:0;s:5:"27160";}
[key_type_2_key_othername] => a:1:{i:0;s:5:"27103";}
[key_type_3_key_othername] => a:1:{i:0;s:5:"27149";}
)
)
Now I need to apply two functions namely, unserialize and array_shift in specified order to extract the scalar values like 27169 and store in another array, how can I do that in one pass of array_map or I have to run array_map two times compulsorily ?
Also one problem is with recursion, only array_walk_recursive handles recursion properly, but in my case if I try below code, I am getting the given error:
return array_walk_recursive($array, function ( &$value ) {
$value = array_shift( unserialize( $value ) );
});
Error:
Strict Standards: Only variables should be passed by reference in /path/to/file.php on line 367
Expected Result:
Array
(
[primary] => Array
(
27232
27231
27147
27157
)
[additional] => Array
(
27169
27160
27103
27149
)
)
With no calls to array_map.
<?php
$data = [
'primary' =>
[
'a:1:{i:0;s:5:"27232";}',
'a:1:{i:0;s:5:"27231";}',
'a:1:{i:0;s:5:"27147";}',
'a:1:{i:0;s:5:"27157";}'
],
'additional' =>
[
'a:1:{i:0;s:5:"27169";}',
'a:1:{i:0;s:5:"27160";}',
'a:1:{i:0;s:5:"27103";}',
'a:1:{i:0;s:5:"27149";}'
]
];
$numbers = [];
foreach($data as $key=>$value) {
foreach($value as $k=>$v) {
$unserialized = unserialize($v);
$numbers[$key][] = (int) array_shift($unserialized);
}
}
var_dump($numbers);
Output:
array (size=2)
'primary' =>
array (size=4)
0 => int 27232
1 => int 27231
2 => int 27147
3 => int 27157
'additional' =>
array (size=4)
0 => int 27169
1 => int 27160
2 => int 27103
3 => int 27149
Here a mutating array_walk example with three array_map calls. Far uglier and harder to read in my eyes, but each their own:
array_walk($data, function(&$v) {
$v = array_map('intval', array_map('array_shift', array_map('unserialize', $v)));
}
);
var_dump($data);
Output:
array (size=2)
'primary' =>
array (size=4)
0 => int 27232
1 => int 27231
2 => int 27147
3 => int 27157
'additional' =>
array (size=4)
0 => int 27169
1 => int 27160
2 => int 27103
3 => int 27149
Allow me to answer the question that was asked. Yes, yes you can... and you nearly had it!
You only needed to change the way that you were accessing the value. Replace the array_shift() call with [0] -- this eliminates the Strict Standards error.
Code: (Demo)
$array=[
'primary' =>
[
'a:1:{i:0;s:5:"27232";}',
'a:1:{i:0;s:5:"27231";}',
'a:1:{i:0;s:5:"27147";}',
'a:1:{i:0;s:5:"27157";}'
],
'additional' =>
[
'a:1:{i:0;s:5:"27169";}',
'a:1:{i:0;s:5:"27160";}',
'a:1:{i:0;s:5:"27103";}',
'a:1:{i:0;s:5:"27149";}'
]
];
array_walk_recursive($array,function(&$v){$v=unserialize($v)[0];});
var_export($array);
Output:
array (
'primary' =>
array (
0 => '27232',
1 => '27231',
2 => '27147',
3 => '27157',
),
'additional' =>
array (
0 => '27169',
1 => '27160',
2 => '27103',
3 => '27149',
),
)

array's key match with another array php

Ex :
First array:
Array
(
[0] => id
[1] => ADDRESS
[2] => ADDRESS1
[3] => name
)
Second array:
Array
(
[id] => 1
[name] => Ankit
[city] => SURAT
)
Required OUTPUT :
[id] => 1
[ADDRESS]=>
[ADDRESS1]=>
[name] => Ankit
here we can see that value of first array ADDRESS,ADDRESS1 doesn't exist in array 2 key,
so i need value to be set null for ADDRESS,ADDRESS1 and unnecessary field of array 2 is city which key doesn't exist in first array values is need to be unset from result array
CODE :
$field_arr= array('0'=>"id",
"1"=>"ADDRESS",
"2"=>"ADDRESS1",
'3'=>"name",
);
$arr=array("id"=>"1",
'name'=>"Ankit",
"city"=>"Ahmedabad");
$matching_fields =(array_diff_key(array_flip($field_arr),(array_intersect_key($arr,array_flip($field_arr)))));
if(!empty($matching_fields)){
foreach($matching_fields as $key=>$value){
$new_arr[$key]=null;
}
}
print_r($new_arr);
exit;
CURRENT OUTPUT OF NEW ARRAY :
Array
(
[ADDRESS] =>
[ADDRESS1] =>
)
but this is long process.as well as performance also matter. i want whole code reconstruct which i have made and just get output which is required output
Here some more need help need i want same sequence of key of output array same as first array value
my required output :
[id] => 1
[ADDRESS]=>
[ADDRESS1]=>
[name] => Ankit
current output :
[id] => 1
[name] => Ankit
[ADDRESS]=>
[ADDRESS1]=>
Thanks in advance
Just try with:
$keys = array('id', 'name', 'ADDRESS', 'ADDRESS1');
$data = array(
'id' => 1,
'name' => 'Ankit',
'city' => 'SURAT',
);
$output = $data + array_fill_keys($keys, null);
Output:
array (size=5)
'id' => int 1
'name' => string 'Ankit' (length=5)
'city' => string 'SURAT' (length=5)
'ADDRESS' => null
'ADDRESS1' => null
$keys = array_unique(array_merge($field_arr, array_keys($arr)));
$new_array = array();
foreach ($keys as $key)
{
$new_array[$key] = isset($arr[$key]) ? $arr[$key] : '';
}
echo "<pre>";
print_r($new_array);
You can use following;
$first = array(
"id",
"name",
"ADDRESS",
"ADDRESS1"
);
$second = array(
"id" => "1",
"name" => "Ankit",
"city" => "SURAT"
);
foreach ($first as $key) {
if ($second[$key] == null) {
$second[$key] = null;
}
}
var_dump($second);
Here is working demo: Demo

Array Combine Question in PHP

HI,
I got two array.
var_dump($tbDateArr);
var_dump($tbTitleArr);
output:
array
0 =>
object(stdClass)[16]
public 'eventDate' => string '5' (length=1)
1 =>
object(stdClass)[17]
public 'eventDate' => string '16' (length=2)
array
0 =>
object(stdClass)[18]
public 'eventTitle' => string 'mar' (length=10)
1 =>
object(stdClass)[19]
public 'eventTitle' => string 'tri' (length=10)
BTW,I print them as this,
print_r($tbDateArr);
echo '<br>';
print_r($tbTitleArr);
Array ( [0] => stdClass Object ( [eventDate] => 5 ) [1] => stdClass Object ( [eventDate] => 16 ) )
Array ( [0] => stdClass Object ( [eventTitle] => mar ) [1] => stdClass Object ( [eventTitle] => tri ) )
I tried to combin them,
$dataArr = array_combine($tbDateArr, $tbTitleArr);
I JUST WANT THE SIMPLY RESULT as this,
Array
(
[5] => mar
[16] => tri
)
Is there anything wrong? Appreciated for your help.
[updated with array_merge]
array
0 =>
object(stdClass)[16]
public 'eventDate' => string '5' (length=1)
1 =>
object(stdClass)[17]
public 'eventDate' => string '16' (length=2)
2 =>
object(stdClass)[18]
public 'eventTitle' => string 'fuzhou mar' (length=10)
3 =>
object(stdClass)[19]
public 'eventTitle' => string 'weihai tri' (length=10)
Assuming that $tbDateArr and $tbTitleArr entries only have a single property (eventDate and eventTitle respectively), you can do this:
$array = array_combine(
array_map('current', $tbDateArr),
array_map('current', $tbTitleArr)
);
If they have (or can have) more than a single property, you're better off using a good old foreach, assuming they have matching keys (if they don't, just array_values them beforehand):
$array = array();
foreach ($tbDateArr as $key => $value) {
$array[$value] = $tbTableArr[$key];
}
You can't directly combine the arrays, since the values you need are stored as properties in objects -- you have to pull these values out and use them:
$keys = array_map('getEventDate', $tbDateArr);
$values = array_map('getEventDate', $tbTitleArr);
print_r(array_combine($keys, $values));
function getEventDate($o) {
return $o->eventDate;
}
EDIT
this works
$arr1 = array(
"5",
"16",
);
$arr2 = array(
"mar",
"tri",
);
$result = array_combine($arr1, $arr2);
print_r($result);
You are trying to combine arrays which containing objects. array_combine using its first argument for keys second argument as values.

Find all second level keys in multi-dimensional array in php

I want to generate a list of the second level of keys used. Each record does not contain all of the same keys. But I need to know what all of the keys are. array_keys() doesn't work, it only returns a list of numbers.
Essentially the output Im looking for is:
action, id, validate, Base, Ebase, Ftype, Qty, Type, Label, Unit
I have a large multi-dimensional array that follows the format:
Array
(
[0] => Array
(
[action] => A
[id] => 1
[validate] => yes
[Base] => Array
(
[id] => 2945
)
[EBase] => Array
(
[id] => 398
)
[Qty] => 1
[Type] => Array
(
[id] => 12027
)
[Label] => asfhjaflksdkfhalsdfasdfasdf
[Unit] => asdfas
)
[1] => Array
(
[action] => A
[id] => 2
[validate] => yes
[Base] => Array
(
[id] => 1986
)
[FType] => Array
(
[id] => 6
)
[Qty] => 1
[Type] => Array
(
[id] => 13835
)
[Label] => asdssdasasdf
[Unit] => asdger
)
)
Thanks for the help!
<?php
// Gets a list of all the 2nd-level keys in the array
function getL2Keys($array)
{
$result = array();
foreach($array as $sub) {
$result = array_merge($result, $sub);
}
return array_keys($result);
}
?>
edit: removed superfluous array_reverse() function
array_keys(call_user_func_array('array_merge', $a));
Merge all values and retrieve the resulting keys.
One liner:
$keys=array_unique(array_reduce(array_map('array_keys',$data),'array_merge',[]));
Or in a function:
function get_array_children_keys($data) {
return array_unique(
array_reduce(array_map('array_keys', $data), 'array_merge', [])
);
}
Now lets break this down with an example, here is some sample data:
[
['key1' => 0],
['key1' => 0, 'key2' => 0],
['key3' => 0]
]
Starting with the inner most function, we run array_map with the array_keys function:
array_map('array_keys', $data)
This gives us the keys of from all child arrays
[
['key1'],
['key1', 'key2'],
['key3']
]
Then we run the array_reduce on the data with the array_merge callback and an empty array as the initial value:
array_reduce(..., 'array_merge', []);
This converts our multiple arrays into 1 flat array:
[
'key1',
'key1',
'key2',
'key3'
]
Now we strip out our duplicates with array_unique:
array_unique(...)
And end up with all our keys:
[
'key1',
'key2',
'key3'
]
foreach($bigArray as $array){
foreach($array as $key=>$value){
echo $key;
}
}
That should do what you want.
What about something like this :
$your_keys = array_keys($your_array[0]);
Of course, this is considering all sub-arrays have the same keys ; in this case, you only need the keys of the first sub-array (no need to iterate over all first-level sub-arrays, I guess)
And, as a shortened / simplified example :
$your_array = array(
array(
'action' => 'A',
'id' => 1,
'base' => array('id' => 145),
),
array(
'action' => 'B',
'id' => 2,
'base' => array('id' => 145),
),
array(
'action' => 'C',
'id' => 3,
'base' => array('id' => 145),
)
);
$your_keys = array_keys($your_array[0]);
var_dump($your_keys);
Will get you :
array
0 => string 'action' (length=6)
1 => string 'id' (length=2)
2 => string 'base' (length=4)
You can the use implode to get the string you asked for :
echo implode(', ', $your_keys);
will get you :
action, id, base
ie, the list of the keys of the first sub-array.
function __getAll2Keys($array_val){
$result = array();
$firstKeys = array_keys($array_val);
for($i=0;$i<count($firstKeys);$i++){
$key = $firstKeys[$i];
$result = array_merge($result,array_keys($array_val[$key]));
}
return $result;
}
try this function. It will return as you want.
While #raise answers provides a shortcut, it fails with numeric keys. The following should resolve this:
$secondKeys=array_unique(call_user_func_array('array_merge', array_map('array_keys',$a)));
array_map('array_keys',$a) : Loop through while getting the keys
...'array_merge'... : Merge the keys array
array_unique(... : (optional) Get unique keys.
I hope it helps someone.
UPDATE:
Alternatively you can use
$secondKeys=array_unique(array_merge(...array_map('array_keys', $a)));
That provides same answer as above, and much faster.
My proposal, similar to this answer but faster and using spread operator (PHP 5.6+).
array_merge(...array_values($fields))
if you want move names to array values and reset keys to 0..n just use array_keys in last step.
array_keys(array_merge(...array_values($fields)))
Maybe you can use array_map function, which allows you to avoid array iteration and return an array with the keys you need as values.
will be like this
$newArray = array_map(function($value){return array_keys($value);},$yourArray);
var_dump($newArray);
array (size=2)
0 =>
array (size=9)
0 => string 'action' (length=6)
1 => string 'id' (length=2)
2 => string 'validate' (length=8)
3 => string 'Base' (length=4)
4 => string 'EBase' (length=5)
5 => string 'Qty' (length=3)
6 => string 'Type' (length=4)
7 => string 'Label' (length=5)
8 => string 'Unit' (length=4)
1 =>
array (size=9)
0 => string 'action' (length=6)
1 => string 'id' (length=2)
2 => string 'validate' (length=8)
3 => string 'Base' (length=4)
4 => string 'FType' (length=5)
5 => string 'Qty' (length=3)
6 => string 'Type' (length=4)
7 => string 'Label' (length=5)
8 => string 'Unit' (length=4)
With this function you can get all keys from a multidimensional array
function arrayKeys($array, &$keys = array()) {
foreach ($array as $key => $value) {
$keys[] = $key;
if (is_array($value)) {
$this->arrayKeys($value, $keys);
}
}
return $keys;
}
Only if all records have the same keys you could do:
$firstItem = reset($array);
$keys = array_keys($firstItem);
Obviously, this is not the correct answer to this specific question, where the records have different keys. But this might be the question you find when looking how to retrieve second level keys from an array where all keys are the same (I did). If all the record have the same keys, you can simply use the first item in the array with reset() and get the keys from the first item with array_keys().

Categories