How do I merge two multi-dimensional arrays using different keys that have matching values?
i.e. I want the data in arrayOne, 'Member'=> '45', to merge with the data in arrayTwo, 'id' => '45'.
I don't have access to the query, just the result array.
First Array:
arrayOne
array (
558 =>
array (
'id' => '558',
'Member' => '45',
'Status' => 'Active',
),
559 =>
array (
'id' => '559',
'Member' => '46',
'Status' => 'Active',
),
)
Second Array:
arrayTwo
array (
45 =>
array (
'id' => '45',
'Name' => 'Johnson',
),
46 =>
array (
'id' => '46',
'Name' => 'Smith',
),
)
Desired Array would be something like this:
arrayThree
array (
45 =>
array (
'id' => '45',
'Name' => 'Johnson',
'Member' => '45',
'Status' => 'Active',
),
46 =>
array (
'id' => '46',
'Name' => 'Smith',
'Member' => '46',
'Status' => 'Active',
),
)
This is the code I've most recently tried, which does merge the records, but it doesn't merge them by their matching values. Thank-you for any help!
function my_array_merge($arrayOne, $arrayTwo) {
$result = arrayThree();
foreach($arrayOne as $key => $value) {
$result[$key] = array_merge($value, $arrayTwo[$key]);
}
return $result;
}
echo "<pre>";
print_r($result);
echo "</pre>";
You can use array_map:
$array1 = array_combine(array_column($array1, 'Member'), $array1);
$result = array_map(function ($item2) use ($array1) {
$item1 = isset($array1[$item2['id']]) ? $array1[$item2['id']] : null;
if ($item2) {
$item2['Member'] = $item1['Member'];
$item2['Status'] = $item1['Status'];
}
return $item2;
}, $array2);
Here is working demo.
Related
I have this array structure:
array (
0 =>
array (
'id' => '17',
'name' => 'aba aba',
'english_name' => 'ABA ABA',
'group_id' => '1',
),
1 =>
array (
'id' => '23',
'name' => 'bcb bcb',
'english_name' => 'BCB BCB',
'group_id' => '2',
),
2 =>
array (
'id' => '17',
'name' => 'aba aba',
'english_name' => 'ABA ABA',
'group_id' => '4',
),
);
I want to create another array with no duplicates but having in mind in which group_id are the duplicate ones. I'm looking for this structure:
array (
17 =>
array (
'name' => 'ABA ABA',
'groups' =>
array (
0 => '1',
1 => '4',
),
),
23 =>
array (
'name' => 'BCB BCB',
'groups' =>
array (
0 => '2',
),
),
);
I tried with this code but it doesn't give me what I'm looking for, I don't know what I'm doing wrong.
Code:
foreach ($array as $value) {
if (!in_array($value['id'], $array[$value['id']] )) {
$interested [$value['id']]['name'] = $value['english_name'];
$interested [$value['id']]['groups'][]= $value['group_id'];
} else if (in_array($value['id'], $array[$value['id']] )){
$interested [$value['id']]['groups'][] = $value['group_id'];
}
}
Simple loop and assign using the id as your pivot:
<?php
$data =
array (
0 =>
array (
'id' => '17',
'name' => 'aba aba',
'english_name' => 'ABA ABA',
'group_id' => '1',
),
1 =>
array (
'id' => '23',
'name' => 'bcb bcb',
'english_name' => 'BCB BCB',
'group_id' => '2',
),
2 =>
array (
'id' => '17',
'name' => 'aba aba',
'english_name' => 'ABA ABA',
'group_id' => '4',
),
);
foreach($data as $item) {
$result[$item['id']]['name'] = $item['english_name'];
$result[$item['id']]['groups'][] = $item['group_id'];
}
var_export($result);
Output:
array (
17 =>
array (
'name' => 'ABA ABA',
'groups' =>
array (
0 => '1',
1 => '4',
),
),
23 =>
array (
'name' => 'BCB BCB',
'groups' =>
array (
0 => '2',
),
),
)
$data = array (
0 =>
array (
'id' => '17',
'name' => 'aba aba',
'english_name' => 'ABA ABA',
'group_id' => '1',
),
1 =>
array (
'id' => '23',
'name' => 'bcb bcb',
'english_name' => 'BCB BCB',
'group_id' => '2',
),
2 =>
array (
'id' => '17',
'name' => 'aba aba',
'english_name' => 'ABA ABA',
'group_id' => '4',
),
);
function unique_multidim_array($array, $key) {
$temp_array = array();
$i = 0;
$key_array = array();
foreach($array as $val) {
if (!in_array($val[$key], $key_array)) {
$key_array[$i] = $val[$key];
$temp_array[$i] = $val;
}
$i++;
}
return $temp_array;
}
$newdata = unique_multidim_array($data,'id');
The function taken from here. Details on : https://www.php.net/manual/tr/function.array-unique.php
It isn't very clear from your code what you are trying to do, but below is one way.
Loop over your subarrays one by one.
have a new array, say $set which will be an associative array of keys and values where keys are the IDs and values are the name and groups attributes.
If $set has the ID isset already, add to groups, else, create a new one and then add groups.
Snippet:
<?php
$set = [];
foreach($array as $val){
$group_id = $val['group_id'];
if(!isset($set[$val['id']])){
$set[$val['id']] = [
'name' => $val['english_name'],
'groups' => []
];
}
$set[$val['id']]['groups'][] = $group_id;
}
print_r($set);
Demo: http://sandbox.onlinephpfunctions.com/code/af65effc35a0275bdf6908c77dc0cb701d36010e
Functional way)
function group( $groups, $item ) {
$id = $item['id'];
if ( !isset($groups[$id]) ) {
$groups[$id] = array (
'name' => $item['name'],
'groups' => array(),
);
}
array_push($groups[$id]['groups'], $item['group_id']);
return $groups;
}
array_reduce($data, 'group', array());
Please take a look at playground
Also to make groups array unique PHP Collections could be used. For example, Set data structure.
I am learning associative arrays. This is what I am doing:
array_push( $classe ,array(
'year'=>$annoClasse,
'section'=>$sezione,
'student'=>$member->first_name." ".$member->last_name)
);
That creates:
array (
0 =>
array (
'year' => 'Secondo',
'section' => 'd',
'student' => 'Stephany Johnson',
),
1 =>
array (
'year' => 'Secondo',
'section' => 'd',
'student' => 'Sandra White',
),
)
How would I create something like this? Basically to have each separate property for the student.
array (
0 =>
array (
'year' => 'Second',
'section' => 'd',
'student' (
'name' => 'Stephany',
'surname' => 'Johnson'
)
),
1 =>
array (
'year' => 'Second',
'section' => 'd',
'student' (
'name' => 'Sandra',
'surname' => 'White'
),
)
)
And how would I then echo the student only?
This can be accomplished with the following code:
array_push( $classe ,array(
'year'=>$annoClasse,
'section'=>$sezione,
'student'=>array(
'name'=>$member->first_name,
'surname'=>$member->last_name
)
);
Then to echo only the student:
foreach ($classe as $c) {
echo $c['student']['name'] . " " . $c['student']['surname'] . PHP_EOL;
}
you can do it like that :
array_push( $classe ,array('year'=>$annoClasse, 'section'=>$sezione, 'student' => array('name' => $student_name, 'surname' => $student_surname)));
use foreach to loop the array and print the values you want :
foreach ($classe as $key => $value) {
echo $value['student']['name']; // or echo $value['student']['surname']; etc..
}
You can assign anything to the array key, it can be a bool, integer, string, or array. In your case just assign a new array to the student key.
array_push( $classe, array(
'year' => $annoClasse,
'section' => $sezione,
'student' => array(
'name' => $member->first_name,
'surname' => $member->last_name
)
));
I'm need to merge two 2d arrays by their time, size, and type values. This should created grouped data where value_one and value_two elements may exist in the same row. If there aren't two rows to merge together, then I need the missing element to be set to null -- this way all rows will have the same elements/structure.
$array1 = [
[
'date' => '2018-06-23',
'size' => 'L',
'type' => 'shoes',
'value_one' => '66',
],
[
'date' => '2018-06-23',
'size' => 'XL',
'type' => 'shirt',
'value_one' => '43',
],
[
'date' => '2018-06-23',
'size' => 'M',
'type' => 'Bag',
'value_one' => '23',
]
];
And
$array2 = [
[
'date' => '2018-06-23',
'size' => 'L',
'type' => 'shoes',
'value_two' => '28',
],
[
'date' => '2018-06-23',
'size' => 'XL',
'type' => 'shirt',
'value_two' => '56',
],
[
'date' => '2018-06-23',
'size' => 'M',
'type' => 'Bag',
'value_two' => '14',
],
[
'date' => '2018-06-23',
'size' => 'S',
'type' => 'Cap',
'value_two' => '29',
]
]
Desired result:
[
[
'date' => '2018-06-23',
'size' => 'L',
'type' => 'shoes',
'value_one' => '66',
'value_two' => '28',
],
[
'date' => '2018-06-23',
'size' => 'XL',
'type' => 'shirt',
'value_one' => '43',
'value_two' => '56',
],
[
'date' => '2018-06-23',
'size' => 'M',
'type' => 'Bag',
'value_one' => '23',
'value_two' => '14',
],
[
'date' => '2018-06-23',
'size' => 'S',
'type' => 'Cap',
'value_one' => null,
'value_two' => '29',
]
]
I want to solve this case with php, laravel or collection "Laravel" class.
I tried to create the array and merge using array_merge_recursive(), array_merge(), or using this code:
foreach ($d as $k => $v) {
$new_arr[$v['date']][] = $v;
}
try
//both arrays will be merged including duplicates
$result = array_merge( $array1, $array2 );
//duplicate objects will be removed
$result = array_map("unserialize", array_unique(array_map("serialize", $result)));
//array is sorted on the bases of id
sort( $result );
For an elegant solution that only needs one loop, use the following:
Hardcode an array of default keys in your desired order.
Merge the arrays and iterate.
Identifying matching data sets by the first three elements in each row.
Depending on whether the composite key has been encountered before, overwrite the default or cached data with the current row.
To remove temporary composite key after looping, call array_values() on the result array.
Code: (Demo)
$defaults = array_fill_keys(['date', 'size', 'type', 'value_one', 'value_two'], null);
$result = [];
foreach (array_merge($array1, $array2) as $row) {
$compositeKey = implode('_', array_slice($row, 0, 3));
$result[$compositeKey] = array_merge($result[$compositeKey] ?? $defaults, $row);
}
var_export(array_values($result));
You can try this
$Array_final= [];
foreach ($Array_one as $key1 => $value1) {
foreach ($Array_two as $key2 => $value2) {
if ($value1['date']==$value2['date']) {
$Array_final[]=$value2+$value1;
}
}
}
You can try this :-
$final = $arr1; // default get all values from first array
foreach ($arr2 as $value) { // loop through second array to match
$flag = 0;
foreach ($final as $key => $data) {
// Check for date, size and type
if ($data['date']===$value['date'] && $data['size']===$value['size'] && $data['type']===$value['type']) {
$final[$key]['value_two'] = $value['value_two'];
$flag = 1;
break;
}
}
if ($flag === 0) { // If similar not found, then add new one
array_push($final, $value);
}
}
print_r($final);
Output :-
Array
(
[0] => Array
(
[date] => 2018-06-23
[size] => L
[type] => shoes
[value_one] => 66
[value_two] => 28
)
[1] => Array
(
[date] => 2018-06-23
[size] => XL
[type] => shirt
[value_one] => 43
[value_two] => 56
)
[2] => Array
(
[date] => 2018-06-23
[size] => M
[type] => Bag
[value_one] => 23
[value_two] => 14
)
[3] => Array
(
[date] => 2018-06-23
[size] => S
[type] => Cap
[value_two] => 29
)
)
Fiddle link :- https://3v4l.org/fSh1V
try
var result = a1.slice(0);
for (var i = 0 ; i < result.length ; i++){
for (var j = 0; j < a2.length ; j++){
if (result[i]. date == a2[j]. date && result[i]. size == a2[j]. size && result[i]. type == a2[j]. type){
result[i]. value_one = a2[j]. value_one;
result[i]. value_two = a2[j].value_two;
}
};
};
console.log(result);
I'm trying to get the occurrences of an array taking in count 1 key value, for example:
$newarray[0] = [
'id' => '2',
'date' => '2016-04-22'
];
$newarray[1] = [
'id' => '2',
'date' => '2016-04-13'
];
$newarray[2] = [
'id' => '2',
'date' => '2016-04-12'
];
$newarray[3] = [
'id' => '1',
'date' => '2016-03-11'
];
$newarray[4] = [
'id' => '2',
'date' => '2016-03-05'
];
$newarray[5] = [
'id' => '1',
'date' => '2016-03-01'
];
I want to transform this, to something like this:
Array ( [0] => Array ( [id] => 1 [date] => 2016-03-11 [occurences] => 2 ) [1] => Array ( [id] => 2 [date] => 2016-04-22 [occurences] => 4 ) )
I tried doing this:
$cleanarray;
$newarray2=$newarray;
$newarray;
$k=0;
$num=1;
for($i=0; $i<count($newarray); $i++){
for($j=1; $j<count($newarray2); $j++){
if($newarray2[$j]["id"]==$newarray[$i]["id"]){
$num++;
}
}
$cleanarray[$k] = [
'id' => $newarray[$i]["id"],
'date' => $newarray[$i]["date"],
'occurences' => $num
];
$k++;
$num=0;
}
But a lot of items repeat, with the same occurrences but several times, and in other cases the repeated items (with same id) would have different occurrences, so I don't know what can I do, I know that there is a function of:
$occurences = array_count_values($array);
But it doesn't work in this case, how can I approach to the solution?
I know what are you looking for, but I think this could solve your problems:
$newarray[0] = [
'id' => '2',
'date' => '2016-04-22'
];
$newarray[1] = [
'id' => '2',
'date' => '2016-04-12'
];
$newarray[2] = [
'id' => '2',
'date' => '2016-04-12'
];
$newarray[3] = [
'id' => '1',
'date' => '2016-03-11'
];
$newarray[4] = [
'id' => '2',
'date' => '2016-03-05'
];
$newarray[5] = [
'id' => '1',
'date' => '2016-03-01'
];
foreach($newarray as $key => $value){
if(isset($found[$value['id']][$value['date']])) {
$found[$value['id']][$value['date']]++;
} else {
$found[$value['id']][$value['date']] = 1;
}
}
print_r($found);
this will return something like:-
Array
(
[2] => Array
(
[2016-04-22] => 1
[2016-04-12] => 2
[2016-03-05] => 1
)
[1] => Array
(
[2016-03-11] => 1
[2016-03-01] => 1
)
)
Using temporary keys for this process will be the most performant way. Temporary keys simplify the output array task, requiring less and faster checking. If you wish to sort on id after the result array is generated, the temporary keys allow a simple ksort() call.
Code: (Demo)
$newarray=[
['id' => '2','date' => '2016-04-22'],
['id' => '2','date' => '2016-04-13'],
['id' => '2','date' => '2016-04-12'],
['id' => '1','date' => '2016-03-11'],
['id' => '2','date' => '2016-03-05'],
['id' => '1','date' => '2016-03-01']
];
foreach($newarray as $a){
if(!isset($result[$a['id']])){
$result[$a['id']]=array_merge($a,['occurrences'=>1]); // use id as temp key, preserve first found date
}else{
++$result[$a['id']]['occurrences']; // only update occurrences to preserve date
}
}
ksort($result); // optionally sort on id ASC
var_export(array_values($result)); // remove temporary keys from first level and print to screen
Output:
array (
0 =>
array (
'id' => '1',
'date' => '2016-03-11',
'occurrences' => 2,
),
1 =>
array (
'id' => '2',
'date' => '2016-04-22',
'occurrences' => 4,
),
)
You can do it like below:-
$final_array = array();
foreach($newarray as $arr){
if(!in_array($arr['id'],array_keys($final_array))){
$final_array[$arr['id']] = $arr;
$final_array[$arr['id']]['occurences'] = 1;
}else{
$final_array[$arr['id']]['occurences'] += 1;
}
}
$final_array= array_values($final_array);
print_r($final_array);
Output:- https://eval.in/847242
Note:- if you want final array to be ascending order of id then use usort() function like below:-
function cmpId($a, $b) {
return ($a['id'] - $b['id']);
}
usort($final_array, "cmpId");
print_r($final_array);
Output:- https://eval.in/847245
I have two arrays
$array1 = array(
0 => array(
'user' => 'user0',
'id' => 'id0'
),
1 => array(
'user' => 'user1',
'id' => 'id1'
),
2 => array(
'user' => 'user2',
'id' => 'id2'
)
);
$array2 = array(
0 => array(
'emp' => 'emp0',
'id' => 'id3'
),
1 => array(
'emp' => 'emp1',
'id' => 'id1'
),
2 => array(
'emp' => 'emp2',
'id' => 'id2'
)
);
i need to loop array 2 first an d give input of id from array1 to the array 1 and search whether the value of id1 from arr1 exists in array2
Maybe this could work? (If I understood your question correctly)
$id_arr = array();
$final_arr = array();
checkArray($array1, $id_arr, $final_arr);
checkArray($array2, $id_arr, $final_arr);
function checkArray($arr, &$id_arr, &$final_arr) {
foreach ($arr as $key => $value) {
if (!in_array($value['id'], $id_arr)) {
$id_arr[] = $value['id'];
$final_arr[] = $value;
}
}
}
var_dump($final_arr);