This question already has answers here:
Merging and group two arrays containing objects based on one identifying column value
(4 answers)
Closed last month.
first arrays has two properties:
id, text
second array has two properties
id, count
How to combine these into one array by id where the new array will have three properties:
id
text
count
First array:
array(2) {
[0]=>
object(stdClass)#351 (2) {
["id"]=>
string(1) "1"
["text"]=>
string(5) "tree"
}
[1]=>
object(stdClass)#348 (2) {
["id"]=>
string(1) "2"
["text"]=>
string(8) "house"
}
second array:
array(2) {
[0]=>
object(stdClass)#351 (2) {
["id"]=>
string(1) "1"
["count"]=>
string(5) "3"
}
[1]=>
object(stdClass)#348 (2) {
["id"]=>
string(1) "2"
["count"]=>
string(8) "4"
}
I tried:
array_merge_recursive, array_merge where these only merge the two arrays together into one long array.
Expected output with above arrays:
array(2) {
[0]=>
object(stdClass)#351 (2) {
["id"]=>
string(1) "1"
["count"]=>
string(5) "3"
string(1) "1"
["text"]=>
string(5) "tree"
}
[1]=>
object(stdClass)#348 (2) {
["id"]=>
string(1) "2"
["count"]=>
string(8) "4"
string(1) "2"
["text"]=>
string(8) "house"
}
You could write a simple function that would merge the properties of the object in the second array if it matches the id of the object in the first array:
function obj_array_merge( $a1, $a2 ) {
$newAry = [];
foreach( $a1 as $idx => $obj1 ) {
// Clone object to prevent alterations to object in $a1
$newAry[$idx] = clone $obj1;
foreach($a2 as $obj2) {
/**
** If id property of both objects match,
** copy properties from second array object
** to new object (clone of first array object).
*/
if( $newAry[$idx]->id === $obj2->id ) {
foreach($obj2 as $prop => $val) {
$newAry[$idx]->$prop = $val;
}
}
}
}
return $newAry;
}
// To run:
$mergedArray = obj_array_merge( $array1, $array2 );
However, note that this is not going to be fast. With a large number of objects it can get quite slow since it has to iterate over both arrays to check for matches. It will also overwrite properties that exist in the new array object with that of the second array object (you didn't specify if that was an issue).
Related
I have an array like this. Each array is having a user ID with scores populated dynamically. I want to add all the strings inside the array and have the key as userID
array(3) {
[13702]=>
array(2) {
[0]=>
string(1) "4"
[1]=>
string(1) "9"
[2]=> .....
..... more elements
}
[13703]=>
array(2) {
[0]=>
string(1) "7"
[1]=>
string(1) "6"
.....
..... more elements
}
[13774]=>
array(1) {
[0]=>
string(1) "7"
.....
..... more elements
}
}
I want to make it like below
array(
'13702'=> 13,//this is the sum of strings inside it
'13703'=> 13,
'13774'=> 7,
);
Please help
No need for array reduce, a simple array_map applying array_sum on each sub array should suffice:
$result = array_map('array_sum', $array);
I am trying to loop through array of arrays in php. Usually get stalked with complex array sometimes but I need your kind assistance with this.
var_dump($array) produced the array below:
$arrayVal = array(6) {
["item_id"]=>
array(2) {
[0]=>
string(1) "1"
[1]=>
string(1) "2"
}
["request_explanation"]=>
array(2) {
[0]=>
string(7) "Welcome"
[1]=>
string(11) "Hello World"
}
["quantity"]=>
array(2) {
[0]=>
string(1) "4"
[1]=>
string(1) "4"
}
["unit_cost"]=>
array(2) {
[0]=>
string(1) "4"
[1]=>
string(1) "3"
}
["total_cost"]=>
array(2) {
[0]=>
string(1) "0"
[1]=>
string(1) "0"
}
["supporting_document"]=>
string(0) ""
}
My database table:
I want to be able to save each of the value in that array into the table above. Thanks for helping me.
Use the indexes of one of the sub-arrays to access all the other sub-arrays:
foreach ($array['item_id'] as $i => $item_id) {
$request_explanation = $array['request_explanation'][$i];
$quantity = $array['quantity'][$i];
// repeat this for all the columns
// Now you can insert all these variables into the database
}
Use a loop to build 2 separate arrays:
foreach($array['ExpensesList'] as $index => $val){
$array1[$index] = $array['ExpensesList'][$index][0];
$array2[$index] = $array['ExpensesList'][$index][1];
}
Then insert each array into your database individually.
This will not work if any sub array contains an index at 2, so this is explicitly for the example structure you provided.
This question already has answers here:
Merging and group two arrays containing objects based on one identifying column value
(4 answers)
Closed 5 months ago.
After I merged two arrays like this array_merge($array1, $array2);, it becomes like this:
array(10) {
[0]=>
object(stdClass) (2) {
["id"]=>
string(1) "1"
["text"]=>
string(5) "one"
}
[1]=>
object(stdClass) (2) {
["id"]=>
string(1) "2"
["text"]=>
string(8) "two"
}
[2]=>
object(stdClass) (2) {
["id"]=>
string(1) "3"
["text"]=>
string(4) "three"
}
[3]=>
object(stdClass) (2) {
["id"]=>
string(1) "4"
["text"]=>
string(8) "four"
}
[4]=>
object(stdClass) (2) {
["id"]=>
string(1) "5"
["text"]=>
string(3) "five"
}
[5]=>
object(stdClass) (2) {
["id"]=>
string(1) "1"
["unit"]=>
string(1) "0"
}
[6]=>
object(stdClass) (2) {
["id"]=>
string(1) "2"
["unit"]=>
int(0)
}
[7]=>
object(stdClass) (2) {
["id"]=>
string(1) "3"
["unit"]=>
int(0)
}
[8]=>
object(stdClass) (2) {
["id"]=>
string(1) "4"
["unit"]=>
string(1) "0"
}
[9]=>
object(stdClass) (2) {
["id"]=>
string(1) "5"
["unit"]=>
int(1)
}
}
Which means both arrays are literally merged. But what I wanted is since both arrays has common property called id and same value for it, it should become like:
array(2) {
[0]=>
object(stdClass) (2) {
["id"]=>
string(1) "1"
["text"]=>
string(5) "one"
["unit"]=>
int(0)
}
[1]=>
object(stdClass) (2) {
["id"]=>
string(1) "2"
["text"]=>
string(8) "two"
["unit"]=>
int(2)
}
}
Note that array1 has id, text while array2 has id and unit.
I did refer here as tried the first answer which suggest to use array_map(), but for me I'm getting error saying argument 1 is not an array.
Combine two arrays into a single array based on a common column value
EDIT:
tried this (doesn't work):
$array1 = array_walk($array1, function(&$value) { $value = (array) $value; })
$array2 = array_walk($array2, function(&$value) { $value = (array) $value; })
function modifyArray($a, $b)
{
if (!empty($a) && !empty($b)) {
return array_merge($a, $b);
} else if (!empty($a) && empty($b)) {
return $a;
} else if (empty($a) && !empty($b)) {
return $b;
}
}
$new = array_map("modifyArray", $array1, $array2);
var_dump($new);
Merging objects is noticeably more tedious than arrays. I'd be tempted to convert the array of objects to an array or arrays in my own project, but I won't for this solution.
Unlike arrays which can enjoy array_merge() or the union operator, objects need to be pushed in manually.
I am temporarily grouping data by using the id values as first level keys in the loop, then optionally sorting by those keys, then re-indexing the output to remove the temporary keys.
Code: (Demo):
$output = [];
foreach ($poorly_merged as $object) {
if (!isset($output[$object->id])) {
$output[$object->id] = $object;
} else {
foreach ($object as $property => $value) {
$output[$object->id]->{$property} = $value;
}
}
}
ksort($output); // optionally order by ids
var_export(array_values($output));
Or:
$output = [];
foreach ($poorly_merged as $object) {
if (!isset($output[$object->id])) {
$output[$object->id] = (object)[];
}
foreach ($object as $property => $value) {
$output[$object->id]->{$property} = $value;
}
}
ksort($output); // optionally order by ids
var_export(array_values($output));
Better practice would be not to merge your twp input arrays to form the $poorly_merged array. You could use iterate the second array of objects and add that data into the first -- this would be a more direct solution.
I am trying to sort a multidimensional array based on 1 field so when I run a foreach loop to loop through it will be sorted in the right order...
I have tried several sources but found very few results on multi-dimensional array sorting...
When I run the loop on the below array it shows id field order as 1|2 i want it to be 2|1 what would be the best way to achieve this?
Basically just sort it in descending order...
Array:
array(2) {
[0]=> array(1) {
[0]=> array(4) {
[0]=> string(1) "1"
["id"]=> string(1) "1"
[1]=> string(0) ""
["invoicenum"]=> string(0) ""
}
}
[1]=> array(1) {
[0]=> array(4) {
[0]=> string(1) "2"
["id"]=> string(1) "2"
[1]=> string(0) ""
["invoicenum"]=> string(0) ""
}
}
}
Have you try this?
array_multisort
<?php
// Obtain a list of columns
foreach ($data as $key => $row) {
$mid[$key] = $row['id'];
}
// Use $data to sort by the common key
array_multisort($mid, SORT_DESC, $data);
?>
i have the following array:
["addToCart"]=>
array(3) {
[1]=>
array(5) {
["aantal"]=>
int(1)
["film_id"]=>
string(1) "1"
["zaal_id"]=>
string(1) "1"
["dag"]=>
string(7) "maandag"
["seats"]=>
array(4) {
[0]=>
string(2) "67"
[1]=>
string(2) "68"
[2]=>
string(2) "69"
[3]=>
string(2) "70"
}
}
You can see that i have an array called "seats" inside the "addToCart" array.There are 4 items in the "seats" array.
what i would like to have is 4 separate arrays, they should all have the same content but each of them needs to have 1 value of "seats".
I'm not sure I got exactly what you're looking to do, but this would result in an array of arrays where each has only one seat:
$seatArrays = array();
foreach ($addToCart as $arr)
{
foreach ($arr["seats"] as $seat)
{
$seatArr = $arr; // Copy the original array
$seatArr["seats"] = $seat; // Replace the "seats" subarray with the current seat
$seatArrays[] = $seatArr;
}
}