combine the same values in array - php

Help me pls combine array values.
I have the same array:
In my case i should save customers name like a key.
Array
(
[Test Name] => Array
(
[0] => Array
(
[name] =>
banana
[id] =>
45002
[quantity] =>
10
)
[1] => Array
(
[name] =>
banana
[id] =>
45002
[quantity] =>
20
)
[3] => Array
(
[name] =>
apple
[id] =>
23402
[qua] =>
1
)
[5] => Array
(
[name] =>
cherry
[id] =>
40017
[qua] =>
7
)
How to get something like this:
Array
(
[Test Name] => Array
(
[0] => Array
(
[name] =>
banana
[id] =>
45002
[quantity] =>
30 // summ quantity but unique name and id
)
[1] => Array
(
[name] =>
apple
[id] =>
23402
[qua] =>
1
)
[2] => Array
(
[name] =>
cherry
[id] =>
40017
[qua] =>
7
)
In my case i should save customers name like a key.
Then i will upload this on a table.

You can use array_map and array_reduce to accomplish it:
$results = array_map(function ($result) {
return array_reduce($result, function ($carry, $item) {
if (isset($carry[$item['id']])) {
$carry[$item['id']]['quantity'] += $item['quantity'];
} else {
$carry[$item['id']] = $item;
}
return $carry;
}, array());
}, $results);
From the documentation:
array_map() returns an array containing all the elements of array1 after applying the callback function to each one.
array_reduce() applies iteratively the callback function to the elements of the array, so as to reduce the array to a single value.
In our case the callback given to the array_reduce function returns a final array which contains unique items by id.

Related

How to merge three arrays according to common key in php

I have three arrays first array include ids and employees name and second array have monthly collection with employee ids and third array have daily collection with employee id and daily collection I want to merge these array with ids and name and dcollection and monthly collection but the desired output is not coming here my first array $ids is
Array
(
[0] => stdClass Object
(
[id] => 1
[name] => Rohit
)
[1] => stdClass Object
(
[id] => 2
[name] => Emop1
)
[2] => stdClass Object
(
[id] => 3
[name] => Pankaj
)
[3] => stdClass Object
(
[id] => 4
[name] => tejpal singh
)
)
second array $q1 is
Array
(
[0] => stdClass Object
(
[name] => Rohit
[id] => 1
[mcollecton] => 100
)
[1] => stdClass Object
(
[name] => Emop1
[id] => 2
[mcollecton] => 1222
)
)
third array $q2 is
Array
(
[0] => stdClass Object
(
[name] => Rohit
[id] => 1
[dcollecton] => 300
)
[1] => stdClass Object
(
[name] => Emop1
[id] => 2
[dcollecton] => 150
)
)
so far what I have tried
$new_array = array();
foreach($ids as $k) {
$q1n = array("id"=>$k->id,"name"=>$k->name);
foreach($q1 as $k1) {
if($k->id==$k1->id){
$mc = array("mc"=>$k1->mcollecton);
array_merge($q1n,$mc);
}
}
foreach($q2 as $k1){
if($k->id==$k1->id){
$dc = array("dc"=>$k1->dcollecton);
array_merge($q1n,$dc);
}
}
$a = array_merge($q1n,$mc);
$av = array_merge($q1n,$dc);
array_push($new_array,$q1n);
}
but the output is coming as
Array
(
[0] => Array
(
[id] => 1
[name] => Rohit
)
[1] => Array
(
[id] => 2
[name] => Emop1
)
[2] => Array
(
[id] => 3
[name] => Pankaj
)
[3] => Array
(
[id] => 4
[name] => tejpal singh
)
)
I want the output be like
Array
(
[0] => Array
(
[id] => 1
[name] => Rohit
[mcollection] => 100
[dcollection] => 300
)
[1] => Array
(
[id] => 2
[name] => Emop1
[mcollection] => 1222
[dcollection] => 150
)
[2] => Array
(
[id] => 3
[name] => Pankaj
[mcollection] => 0
[dcollection] => 0
)
[3] => Array
(
[id] => 4
[name] => tejpal singh
[mcollection] => 0
[dcollection] => 0
)
)
So I have tried many times but the desired output is not coming . please help me out how to get the desired output.
It seemed like that answer could be modified, or put in a function that you could call multiple times if needed to combine more than two arrays.
There's probably cleaner ways to handle this with array functions like array_merge or array_walk, but this is the general idea of how I might approach it. I haven't tested this, but maybe it's useful.
foreach($first as $key1 => $value){
foreach($second as $key2 => $value2){
// match the ids and check if array key exists on first array
if($value['id'] === $value2['id'] && empty($first[$key2])){
$first[$key][$key2] = $value2;
}
}
}
EDIT: Based on the answer you posted vs the question you asked, are you incrementing the collection numbers or just setting them? In other words why use +=? You should also be able to remove array_merge and array_push.
Below is geared more towards what you're trying to do. I haven't tested this either, but if you run into errors, post your code with the errors returned so that it's easier to debug:
foreach($ids as $k)
{
$thisArray = $newArray[] = array("id"=>$k->id,"name"=>$k->name);
foreach($q1 as $k1)
{
if($k->id == $k1->id && !empty($k1->mcollecton))
{
$thisArray['mc'] = $k1->mcollecton;
}
}
foreach($q2 as $k2)
{
if($k->id == $k2->id && !empty($k2->dcollecton))
{
$thisArray['dc'] = $k2->dcollecton;
}
}
}
// This should have both new collections fields on all array items
print_r($newArray)

Efficient way to remove key-value from Array of Arrays

I have an array of 50000 arrays and i want to remove the "id" key-value pair from each of them.
I would rather not loop through 50k elements and was wondering if there was an efficient way to do it.
Array
(
[0] => Array
(
[id] => 713061
[market] => usd-btc
[price] => 3893.69
)
[1] => Array
(
[id] => 713056
[market] => usd-btc
[price] => 3893.69
)
[2] => Array
(
[id] => 713051
[market] => usd-btc
[price] => 3893.69
)
[3] => Array
(
[id] => 713046
[market] => usd-btc
[price] => 3893.69
)
[4] => Array
(
[id] => 713041
[market] => usd-btc
[price] => 3892.95
)
[5] => Array
(
[id] => 713036
[market] => usd-btc
[price] => 3892.95
)
I tried both the following but does not seem to be working:
// Remove ID
foreach($server_data as $sd)
{
unset($sd['id']);
}
unset($server_data['id']);
PRINT_R($server_data);
The $server_data is still returning the array with the $id element;
Any thoughts?
This creates a copy of the subarray, so when you change it, the main array is not affected:
foreach ($server_data as $sd)
{
unset($sd['id']);
}
You can unset from the original array:
foreach (array_keys($server_data) as $index)
{
unset($server_data[$index]['id']);
}
Or pass the subarray a reference so that the original is changed:
foreach ($server_data as &$sd)
{
unset($sd['id']);
}
Or, more tersely:
array_walk($server_data, function (&$item) { unset($item['id']); });
There's no reason I can think of to remove it (just ignore it), however you can run it through a callback that removes id and returns the rest:
$server_data = array_map(function($v) { unset($v['id']); return $v; }, $server_data);

PHP - Merge 2 arrays of object using a key/id

I want to merge the 2 arrays of objects based on the 'id' field of Array1 and the 'itemVendorCode' of Array2. I also wanted to remove from the resulting arrays of object anything that didn't match.
Array1:
Array
(
[0] => stdClass Object
(
[id] => 10-423-1176
[qty] => 2
[price] => 12.6
)
[1] => stdClass Object
(
[id] => 89-575-2354
[qty] => 24
[price] => 230.35
)
[2] => stdClass Object
(
[id] => 89-605-1250
[qty] => 2
[price] => 230.35
)
)
Array2:
Array
(
[0] => Item Object
(
[internalId] => 14062
[itemVendorCode] => 89-605-1250
)
[1] => Item Object
(
[internalId] => 33806
[itemVendorCode] => 89-575-2354
)
[2] => Item Object
(
[internalId] => 64126
[itemVendorCode] => 26-295-1006
)
)
I was able to solve this by this code:
$indexed = array();
foreach($itemsArray as $value) {
$indexed[$value->itemVendorCode] = $value;
}
$results = array();
foreach($vendorItems as $obj) {
$value = $indexed[$obj->id];
if (isset($value)) {
foreach($value as $name => $val) {
$obj->$name = $val;
array_push($results, $obj);
}
}
}
print_r($results);
credits to the original poster. I just modified it a bit,
I was able to get the result like this:
Array
(
[0] => stdClass Object
(
[id] => 10-423-1176
[qty] => 2
[price] => 12.6
[internalId] => 2035
[itemVendorCode] => 10-423-1176
)
[1] => stdClass Object
(
[id] => 10-423-1176
[qty] => 2
[price] => 12.6
[internalId] => 2035
[itemVendorCode] => 10-423-1176
)
[2] => stdClass Object
(
[id] => 14-102-1010
[qty] => 16
[price] => 3.2
[internalId] => 57033
[itemVendorCode] => 14-102-1010
)
)
I think you will have to use array_map function which provides you a callback function to execute on array(s).
In the callback function:
- declare your array1
- foreach the second array
- set an if statement to check that the current iteration with the id value matches the itemVendorCode of the array2 and return it
something like this:
// You have to specify to PHP to use a local copy of your $array2 to works with it into your callback
$cb = function ($obj1) use ($array2)
{
// you foreach this array
foreach ($array2 as $obj2) {
// if the value of id matches itemVendorCode
if ($obj1->id === $obj2->itemVendorCode) {
// you return the id
return $obj->id;
}
}
};
// this function will fill a new array with all returned data
$mergedArray = array_map($cb, $array1);
This code is a sample but doesn't provide you, your needled solution, try to update it to do what you exactly want ;)

Combine and sum values in multi-dimensional associative array using php

I have an associative array that looks like this:
Array (
[0] => Array (
[amount] => 3
[name] => Chuck
)
[1] => Array (
[amount] => 2
[name] => Steve
)
[2] => Array (
[amount] => 5
[name] =>
)
[3] => Array (
[amount] => 4
[name] => Chuck
)
[4] => Array (
[amount] =>
[name] => Chuck
)
)
I need to remove values that are missing a name or amount e.g. [2] and [4] and then sum the totals for each name so that the final array is:
Array (
[0] => Array (
[amount] => 7
[name] => Chuck
)
[1] => Array (
[amount] => 2
[name] => Steve
)
)
For anyone looking for this nowadays, this would be much cleaner:
$sum = array_sum(array_column($data, 'amount'));
Try this:
$starting_array = array( ... ); // Initial array with your setup
$final_array = array();
$sum = 0;
foreach ($starting_array as $idx => $data) {
if (!empty($data['amount']) && !empty($data['name'])) {
$final_array[$idx] = $data;
$sum += $data['amount'];
}
}
// After looping through all of the items, $final_array should contain all
// of the specific items that have an amount and name set. In addition, the
// total of all of the amounts will be in $sum.
Take a look at php's empty(). Note: If 0 is an allowed value, you may want to use is_null() instead.

Opposite function of strpos to grab values that do not match a specific pattern in a string or array

What is a function I can use that's basically the opposite of doing
if(strpos($array['some_key'], $value)!==false) {
that means there's a match and confinue
}
I basically want to loop through two arrays and grab the ones that don't have a match to the $value in $array.
$array =
Array
(
[0] => GPPZ20
[1] => GPPZ45
[2] => GPPZ75
[3] => GPPZH20
[4] => GPPZH45
)
$codes =
Array
(
[0] => Array
(
[count] => 1
[code] => GPPZH20SWYE4A2VZU
[amount] => 20
)
)
Array
(
[0] => Array
(
[count] => 1
[code] => GPPZH2077434178J6
[amount] => 20
)
)
Array
(
[0] => Array
(
[count] => 17
[code] => PMMC4
[amount] => 25
)
)
Array
(
[0] => Array
(
[count] => 1
[code] => GPPZH2052910M8V62
[amount] => 20
)
)
Array
(
[0] => Array
(
[count] => 1
[code] => GPPZH45B3116LD1VW
[amount] => 45
)
)
so what i want to do is grab all the ones in the $codes array where the $codes['code'] value does not match any of the ones in the $array value.
right now i have the ones that match and grabbing those by doing
foreach($codes as $code) {
foreach($array as $key=>$value) {
if(strpos($code['code'], $value)!==false) {
//it matches grab those values
}
}
}
I basically now need something like this to grab the ones that do not match
You should use array_filter function - http://php.net/manual/en/function.array-filter.php e.g.:
function myFilter($val){ return strpos('foo', $val) === false; }
$array = array("foobar", "foo", "bar");
var_dump(array_filter($array, myFilter));
You can also use preg_match method instead of strpos.

Categories