I have multiple result from mysql in array like this
Array1
Array
(
[type] => Food
[storage] => S5213
[quantity1] => 1000
[in1] => 10/09/2017
[quantity2] => 1000
[in2] => 10/09/2017
)
Array 2
Array
(
[type] => Food
[storage] => S4512
[quantity1] => 990
[in1] => 13/09/2017
)
Array 3
Array
(
[type] => Drink
[storage] => K4221
[quantity1] => 12000
[in1] => 12/09/2017
)
So, i would like to merge if the key such as "type" from different arrays are same and put it into custom array. At the same time, it maybe has quantity1, quantity2, quantity3 and in1,in2,in3 for different stocks quantity and date. Would like to merge it into "rack".
Expected result
Array
(
[Food] => Array
(
[0] => Array
(
[storage] => S5213
[rack] => Array
(
[0] => Array
(
[quantity] => 1000
[in] => 10/09/2017
)
[1] => Array
(
[quantity] => 1000
[in] => 10/09/2017
)
)
)
[1] => Array
(
[storage] => S4512
[rack] => Array
(
[0] => Array
(
[quantity] => 990
[in] => 13/09/2017
)
)
)
)
[Drink] => Array
(
[0] => Array
(
[storage] => K4221
[rack] => Array
(
[0] => Array
(
[quantity] => 12000
[in] => 12/09/2017
)
)
)
)
)
Is it possible? tried using array_merge_recursive, but not output expected result.
If this is what your SQL query returns, then it looks like your database is not normalised. More concretely, you should not have columns quantity1, quantity2, ...etc in a single table. The rule is, if you have more than one of some field, create a separate table. In this case that table should just have a foreign key, maybe a sequence number (1, 2, ...) and finally a single quantity column. Multiple quantities would be expressed as multiple rows in that additional table. The in field could be added to that, as it seems to follow the same rule.
Anyway, for the given situation, you could use this PHP function:
function addArray(&$main, $arr) {
if (!is_array($main)) $main = []; // first time
$main[$arr["type"]][] = [
"storage" => $arr["storage"],
"rack" => array_reduce(array_keys($arr), function ($acc, $key) use ($arr) {
if (strpos($key, "quantity") === 0) {
$acc[] = [
"quantity" => $arr[$key],
"in" => $arr[str_replace("quantity", "in", $key)]
];
}
return $acc;
}, [])
];
}
Use it as follows:
$arr = [
"type" => "Food",
"storage" => "S5213",
"quantity1" => 1000,
"in1" => "10/09/2017",
"quantity2" => 1000,
"in2" => "10/09/2017"
];
addArray($main, $arr);
$arr = [
"type" => "Food",
"storage" => "S4512",
"quantity1" => 990,
"in1" => "13/09/2017"
];
addArray($main, $arr);
$arr = [
"type" => "Drink",
"storage" => "K4221",
"quantity1" => 12000,
"in1" => "12/09/2017"
];
addArray($main, $arr);
... etc. $main will have the desired structure.
Related
I try to compare arrays and divide it for three different arrays based on subarray with key "ProductID"
Input data look like:
Cat Array:
Array
(
[0] => Array
(
[catID] => Array
(
[0] => 65
[1] =>66
)
[discount] => 10
[productID] => Array
(
[0] => 10887
[1] => 8508
[2] => 8056
)
[startDate] => 05/12/2022 12:00 am
[endDate] => 10/12/2022 12:00 am
)
)
Tax Array:
Array
(
[0] => Array
(
[taxID] => 2436
[discount] => 5
[productID] => Array
(
[0] => 8018
[1] => 8009
)
)
[1] => Array
(
[taxID] => 2438
[discount] => 10
[productID] => Array
(
[0] => 13184
[1] => 8009
)
)
)
When in tax array does not exists any productID from Cat Array, output for this array should look like:
$taxNoDuplicates = [
'discount' => '',
'productIds' => []
];
When in Cat Array does not exists any productID from Tax Array, output for this array should look like:
$catNoDuplicates = [
'discount' => '',
'startDate' => '',
'endDate' => '',
'productIds' => []
];
And if duplicates exsits in Cat Array and Tax Array output for this array should look like: :
$taxAndCatCombine = [
'discountTax' => '',
'discountCat' => '',
'startDate' => '',
'endDate' => '',
'productIds' => []
];
Is it possible to create output arrays the way I provided?
My input is:
$item = [
['invoice_id' => '72,', 'item' => 'SN00001'],
['invoice_id' => '73,', 'item' => 'SN00002'],
['invoice_id' => '73,', 'item' => 'SN00003'],
['invoice_id' => '73,', 'item' => 'SN00004'],
['invoice_id' => '74,', 'item' => 'SN00005'],
['invoice_id' => '74,', 'item' => 'SN00006']
];
I want to re-group it with the invoice_id like this
[0] => Array
(
[invoice_id] => 72
[group] => Array
(
[0] => Array
(
[invoice_id] => 72,
[item] => SN00001
)
)
)
[1] => Array
(
[invoice_id] => 73
[group] => Array
(
[0] => Array
(
[invoice_id] => 73,
[item] => SN00002
)
[1] => Array
(
[invoice_id] => 73,
[item] => SN00003
)
[2] => Array
(
[invoice_id] => 73,
[item] => SN00004
)
)
)
[2] => Array
(
[invoice_id] => 74
[group] => Array
(
[0] => Array
(
[invoice_id] => 74,
[item] => SN00005
)
[1] => Array
(
[invoice_id] => 74,
[item] => SN00006
)
)
)
This is what I did so far
$items = [];
foreach($item as $k => $val){
if(empty($items)){
// if first row
$items[$k]['invoice_id'] = $val['invoice_id'];
$items[$k]['group'] = [$val];
} else {
if(!empty($items)){
foreach($items as $key => $value){
if($value['invoice_id'] == $val['invoice_id']){
// if same invoice_id merge the value into the group
$items[$key]['group'] = array_merge($items[$key]['group'], [$val]);
} else {
// else create a array group
$items[$k]['invoice_id'] = $val['invoice_id'];
$items[$k]['group'] = [$val];
}
}
}
}
}
Sample: https://onecompiler.com/php/3y2hgzk79
The issue with my current codes is, it will create a duplicate item in some group. I was trying to use array_search and array_column but it didn't go as expected result so I switched to foreach instead and here I am. Any help will be much appreciated.
I have no idea why there is any need to call array_filter(), array_column(), array_search(), array_merge(), or array_unique(). Grouping the related data is matter of assigning temporary first-level keys, then unconditionally declaring or pushing the row data into the group. If you want to re-index the result array, just call array_values() after the loop finishes.
Code: (Demo)
$array = [
['invoice_id' => '72,', 'item' => 'SN00001'],
['invoice_id' => '73,', 'item' => 'SN00002'],
['invoice_id' => '73,', 'item' => 'SN00003'],
['invoice_id' => '73,', 'item' => 'SN00004'],
['invoice_id' => '74,', 'item' => 'SN00005'],
['invoice_id' => '74,', 'item' => 'SN00006']
];
$result = [];
foreach ($array as $row) {
$result[$row['invoice_id']]['invoice_id'] = $row['invoice_id'];
$result[$row['invoice_id']]['group'][] = $row;
}
var_export(array_values($result));
// output: exactly as desired in the question
Here's a fairly concise solution based on some built-in PHP array handling functions (array_map, array_filter, array_unique and array_column). It uses array_column and array_unique to get a list of distinct invoice_id values, then array_map to generate the output, filtering the input array for each entry based on whether the invoice_id values match:
$items = array_map(function ($inv_id) use ($item) {
return array('invoice_id' => $inv_id,
'group' => array_filter($item,
function ($itm) use ($inv_id) {
return $itm['invoice_id'] == $inv_id;
})
);
}, array_unique(array_column($item, 'invoice_id'))
);
Output:
Array
(
[0] => Array
(
[invoice_id] => 72,
[group] => Array
(
[0] => Array
(
[invoice_id] => 72,
[item] => SN00001
)
)
)
[1] => Array
(
[invoice_id] => 73,
[group] => Array
(
[1] => Array
(
[invoice_id] => 73,
[item] => SN00002
)
[2] => Array
(
[invoice_id] => 73,
[item] => SN00003
)
[3] => Array
(
[invoice_id] => 73,
[item] => SN00004
)
)
)
[4] => Array
(
[invoice_id] => 74,
[group] => Array
(
[4] => Array
(
[invoice_id] => 74,
[item] => SN00005
)
[5] => Array
(
[invoice_id] => 74,
[item] => SN00006
)
)
)
)
Note that internal array numbering does not start at 0; if you need that then add array_values to re-index in the appropriate places:
$items = array_values(array_map(function ($inv_id) use ($item) {
return array('invoice_id' => $inv_id,
'group' => array_values(array_filter($item,
function ($itm) use ($inv_id) {
return $itm['invoice_id'] == $inv_id;
}))
);
}, array_unique(array_column($item, 'invoice_id'))
));
Demo on 3v4l.org
I have a multi dimension array like below:
Array
(
[1200] => Array
(
[B] => Array
(
[4] => Array
(
[Name] => 'Joe']
)
)
[A] => Array
(
[3] => Array
(
[Name] => 'Paul']
)
)
)
[1100] => Array
(
[F] => Array
(
[2] => Array
(
[Name] => 'Sam']
)
)
[D] => Array
(
[1] => Array
(
[Name] => 'Jane']
)
)
)
What I wish to achieve is having the 4 digit number 1100 and 1200 in order ascending, then I need the letters (B A) and (F D) also in order, and then the single digit number under them in order ascending too. I believe I'm looking at a multi dimension array but any help would be appreciated.
The below function might be what you're looking for. It recursively orders arrays by their key.
function ksort_r(&$array) {
foreach ($array as &$value) {
if (is_array($value)) {
ksort_r($value);
}
}
return ksort($array);
}
Example usage
function ksort_r(&$array) {
foreach ($array as &$value) {
if (is_array($value)) {
ksort_r($value);
}
}
return ksort($array);
}
$data = [
1200 => [
'B' => [
4 => [
'Name' => 'Joe'
]
],
'A' => [
3 => [
'Name' => 'Paul'
]
]
],
1100 => [
'F' => [
2 => [
'Name' => 'Sam'
]
],
'D' => [
1 => [
'Name' => 'Jane'
]
]
]
];
ksort_r($data);
print_r($data);
The above will output...
Array
(
[1100] => Array
(
[D] => Array
(
[1] => Array
(
[Name] => Jane
)
)
[F] => Array
(
[2] => Array
(
[Name] => Sam
)
)
)
[1200] => Array
(
[A] => Array
(
[3] => Array
(
[Name] => Paul
)
)
[B] => Array
(
[4] => Array
(
[Name] => Joe
)
)
)
)
I have an array of arrays, and I want to filter that array by multiple key values, and group the arrays with matching keys if there are any. Example array:
Array
(
[0] => Array
(
[id] => 1
[value] => 11
[quantity] => 14
)
[1] => Array
(
[id] => 2
[value] => 11
[quantity] => 14
)
[2] => Array
(
[id] => 3
[value] => 22
[quantity] => 14
)
[3] => Array
(
[id] => 4
[value] => 22
[quantity] => 14
)
[4] => Array
(
[id] => 5
[value] => 23
[quantity] => 15
)
)
and let's say I want the arrays with matching value and quantity to be grouped in a new array
The desired output would be something like this:
Array
(
[11] => Array
(
[0] => Array
(
[id] => 1
[value] => 11
[quantity] => 14
)
[1] => Array
(
[id] => 2
[value] => 11
[quantity] => 14
)
)
[22] => Array
(
[0] => Array
(
[id] => 3
[value] => 22
[quantity] => 14
)
[1] => Array
(
[id] => 4
[value] => 22
[quantity] => 14
)
)
[23] => Array
(
[0] => Array
(
[id] => 5
[value] => 23
[quantity] => 15
)
)
)
I'm clueless on how to achieve this.
A simple foreach loop over your array to ceate a new array will suffice for this purpose
$new_arr = [];
foreach ($inArray as $arr ) {
$new_arr[$arr['value']][] = $arr;
}
// unset the original array if you are finished with it
// in case it is large and you could make better use
// of the memory for something else
unset($inArray);
If you want to group by the values of multiple keys of the inner arrays, you can join those values together to form the key in your result array.
foreach ($array as $item) {
// combine value and quantity, for example
$key = $item['value'] . '|' . $item['quantity'];
$result[$key][] = $item;
}
just pass an array References and a sort key
function sortBy(&$arr,$by){
$result=array();
foreach($arr as $value){
if(isset($value[$by]))
$result[$value[$by]][]=$value;
}
return $result;
}
Examples
$sorted=sortBy($yourArray,'value'); //by value
$sorted=sortBy($yourArray,'id'); //by Idx
$sorted=sortBy($yourArray,'quantity'); //quantity
You want to group the array keys passing, if I understood correctly.
I usually use the laravel collection library, because it's provided out of the box.
ALthoug, here's my contribution.
Let's try:
function groupArray( $array, $key, $remove = null )
{
$result = array();
foreach (array_unique(array_column($array, $key)) as $value) {
$result[$value] = array_map(function ( $item ) use ( $remove ) {
unset($item[$remove]);
return $item;
}, array_filter($array, function ( $item ) use ( $value, $key ) {
return $item[$key] === $value;
}));
}
return $result;
}
The above function does the job, first we get all the selected key values using the array_column function. THen we do a foreach in the array to filter the array data using the provided key and finally we remove the selected key, if necessary (just because the selected key will be the grouped array keys).
Usage:
$sample = array(
[
'id' => 1,
'value' => 11,
'quantity' => 14
],
[
'id' => 2,
'value' => 11,
'quantity' => 14
],
[
'id' => 3,
'value' => 22,
'quantity' => 14
],
[
'id' => 4,
'value' => 22,
'quantity' => 14
],
[
'id' => 5,
'value' => 23,
'quantity' => 14
],
);
$a = groupArray($sample, 'value', 'value');
$b = groupArray($sample, 'value');
$c = groupArray($sample, 'quantity');
I'd like to merge two arrays on same key. I've tried my best to do it but unable to get success. I've added both the Arrays below. Kindly check both the Arrays in detail and help me how to merge it using same key.
Here's the 1st array :
Array
(
[1] => Array
(
[costprice1] => 500
[margin1] => 20
)
[2] => Array
(
[costprice2] => 600
[margin2] => 15
)
[3] => Array
(
[costprice3] => 700
[margin3] => 25
)
)
Here's the 2 array :
Array
(
[1] => Array
(
[entityType1] => Products1
)
[2] => Array
(
[entityType2] => Products2
)
[3] => Array
(
[entityType3] => Products3
)
)
i want to need like that array please suggestion me
Array
(
[1] => Array
(
[entityType1] => Products1
[costprice1] => 500
[margin1] => 20
)
[2] => Array
(
[entityType2] => Products2
[costprice2] => 600
[margin2] => 15
)
[3] => Array
(
[entityType3] => Products3
[costprice3] => 700
[margin3] => 25
)
)
please help me how to merge two array
Try this :
foreach($array1 as $key => $value) {
$array1[$key]['entityType'.$key] = $array2[$key]['entityType'.$key];
}
print_r($array1);
<?php
$array1 = [
1 => [
'costprice1' => 500,
'margin1' => 20
],
2 => [
'costprice2' => 600,
'margin2' => 15
],
3 => [
'costprice2' => 700,
'margin2' => 25
],
];
$array2 = [
1 => ['entityType1' => 'Products1'],
2 => ['entityType2' => 'Products2'],
3 => ['entityType3' => 'Products3'],
];
array_walk($array2, function(&$v, $k)use($array1){
$v = array_merge($v, $array1[$k]);
});
print_r($array2);
Output:
Array
(
[1] => Array
(
[entityType1] => Products1
[costprice1] => 500
[margin1] => 20
)
[2] => Array
(
[entityType2] => Products2
[costprice2] => 600
[margin2] => 15
)
[3] => Array
(
[entityType3] => Products3
[costprice2] => 700
[margin2] => 25
)
)
https://eval.in/618561