PHP - array_map 2 columns and remove duplicate rows by key [duplicate] - php

This question already has answers here:
Filter/Remove rows where column value is found more than once in a multidimensional array
(4 answers)
Closed 9 months ago.
I have the following array dynamically generated from an external API:
$purchases = array(
array('product_id' => 7, 'receipt' => R13D13),
array('product_id' => 5, 'receipt' => Y28Z14),
array('product_id' => 7, 'receipt' => R02310),
array('product_id' => 5, 'receipt' => E11403)
);
Desired output:
$purchases_new = array(
array('product_id' => 7, 'receipt' => R13D13),
array('product_id' => 5, 'receipt' => Y28Z14)
);
Due to the nature of the API I have only been able to pull data using array_map:
$purchases_unique = array_unique(
array_map(function($pid){ return $pid['product_id']; }, $purchases)
);
print_r($purchases_unique);
Outputs
array((array[251] => 7) array([252] => 5))
Output completely not what I want :( How to array_map 2 columns product_id' and receipt and remove duplicate rows based on product_id?
I want to achieve the following:
array_map both columns? (product_id and receipt)
Remove product_id duplicates rows based on product_id key?

If you want the first occurrence use #TheFirstBird answer. If you want the last occurrence you can do it simpler buy using array_column and array_values as:
$newArr = array_values(array_column($purchases, null, "product_id"));
Notice the second argument of array_column is null meaning take the entire element.
Live example: 3v4l
References: array-column, array-values

I think this will do what you're looking for:
Just adds the unique product_ids (with receipt) to a new array:
$purchases_new = array_reduce($purchases, function($acc, $p) {
if(!in_array($p['product_id'], array_column($acc, 'product_id'))) {
$acc[] = $p;
}
return $acc;
}, []);
Output:
array (
0 =>
array (
'product_id' => 7,
'receipt' => 'R13D13',
),
1 =>
array (
'product_id' => 5,
'receipt' => 'Y28Z14',
),
)
Try it online!

As per the comment It does not matter if it's the first or last occurrence, you could use a foreach and create a $result array for the non duplicates.
For every iteration, use the product_id as the array key and check if it already has been set.
If it is not, then add it.
$purchases = array(
array('product_id' => 7, 'receipt' => "R13D13"),
array('product_id' => 5, 'receipt' => "Y28Z14"),
array('product_id' => 7, 'receipt' => "R02310"),
array('product_id' => 5, 'receipt' => "E11403")
);
$result = [];
foreach($purchases as $key => $purchase) {
if (!isset($result[$purchase["product_id"]])) {
$result[$purchase["product_id"]] = $purchase;
}
}
print_r($result);
Result
Array
(
[7] => Array
(
[product_id] => 7
[receipt] => R13D13
)
[5] => Array
(
[product_id] => 5
[receipt] => Y28Z14
)
)
Php demo

Related

How to create a new array using of another array keys?

Is it possible to create a new array from the keys of another like following?
it is a dynamic array chk_values are dynamically changed depends on condition
Array
(
[actBtn] => update
[chkCount] => 5
[chk_1] => 2
[chk_2] => 3
[chk_3] => 2
[chk_4] => 3
[chk_5] => 3
)
and i want array like this for update database
$chckpoint = Array(
[chk_1] => 2
[chk_2] => 3
[chk_3] => 2
[chk_4] => 3
[chk_5] => 3)
Simply process the original array and only move to the new array where the key starts with chk_
$in = ['actBtn' => 'update',
'chkCount' => 5,
'chk_1' => 2,
'chk_2' => 3,
'chk_3' => 2,
'chk_4' => 3,
'chk_5' => 3
];
foreach($in as $k=>$v){
if ( strpos($k,'chk_') !== false ){ $chckpoint[$k] = $v; }
}
print_r($chckpoint);
RESULT
Array
(
[chk_1] => 2
[chk_2] => 3
[chk_3] => 2
[chk_4] => 3
[chk_5] => 3
)
You can simply take the input array and check for all keys beginning with chk_. If the key matches, take it to the new array.
$chckpoint = [];
foreach($input as $key => $value)
{
if(substr($key, 0, 4) == 'chk_') $chkpoint[$key] = $value;
}

using foreach loop to delete last element from associative array

I want to delete price index from each of the array.
Here is a sample code:
Array([0] => Array
(
[player_id] => 108
[trnmnt_team_id] => 1
[player_type] => 1
[user_team_id] => 11
[user_id] => 4
[price] => 10.00
)
[1] => Array
(
[player_id] => 151
[trnmnt_team_id] => 2
[player_type] => 1
[user_team_id] => 11
[user_id] => 4
[price] => 10.00
)
)
I tried to delete following way but it shown unexpected 'unset' (T_UNSET):
foreach ($mergeAllType as $key => $value) {
$price=$value;
$withOutPrice[]=unset($price['price']);
}
unset doesn't returns any value (it's language construct, not a function), you must do it following way:
unset($price['price']);
$withOutPrice[] = $price;
Tomas.lang's answer works fine if you know the last index's key. However if you don't know the name of the last key you could use the following:
unset(end($price));
$withOutPrice = $price;
You already got your answers regarding your foreach loop.
So, let me give you a different answer, using array_map and an anonymous function ;-)
<?php
$src = array(
array (
'player_id' => 108,
'trnmnt_team_id' => 1,
'player_type' => 1,
'user_team_id' => 11,
'user_id' => 4,
'price' => 10.00,
),
array (
'player_id' => 151,
'trnmnt_team_id' => 2,
'player_type' => 1,
'user_team_id' => 11,
'user_id' => 4,
'price' => 10.00,
),
);
$withOutPrice = array_map(
function($e) {
unset($e['price']);
return $e;
},
$src
);
var_export($withOutPrice);
If you want to unset() all off the price keys in your array you can use array_walk()
array_walk($arr, function(&$array) {
unset($array['price']);
});
Just replace $arr with whatever your arrays name is, i.e. $teams.
If you want to have two arrays, one with price and one without price you could duplicate the array before doing the above; i.e.
$teams = <DATASOURCE>
$teamsWithoutPrice = $teams;
array_walk($teamsWithoutPrice, function(&$array) {
unset($array['price']);
});
Then if you print out your $teamsWithoutPrice array you'll have your array with the price key removed.
Hope it helps.

Appending multiple values to associative array in PHP [duplicate]

This question already has answers here:
Merge two 2d arrays by shared column value
(6 answers)
Closed last month.
I would like to create a PHP array that will end up looking like this:
idPlayer namePlayer Points
1 John 20
2 Sam 25
3 Ben 22
But I would like to append the values not all at once:
First append the idPlayer and namePlayer
Then append the points for that idPlayer (I would have a $idPlayer variable to use each time I loop)
How could I do this in PHP?
I was thinking:
$myArray['idPlayer'] = "1";
$myArray['namePlayer'] = "John";
$myArray['Points'] = "20"
And then, how would I tell the array to go to the next row?
// output array
$myArray = array();
// your loop
while (something) {
// make an array for this iteration
$itarr = array();
// put stuff in it
$itarr['idPlayer'] = "1";
$itarr['namePlayer'] = "John";
$itarr['Points'] = "20"
// append it to output array using standard array indexing
$myArray[] = $itarr;
// OR, your own index
$myArray[$itarr['idPlayer']] = $itarr;
}
I dont know why you want to achieve such thing. But consider this example:
// like player table array initial
$players = array(
array(
'idPlayer' => 1,
'namePlayer' => 'John',
),
array(
'idPlayer' => 2,
'namePlayer' => 'Sam',
),
array(
'idPlayer' => 3,
'namePlayer' => 'Ben',
),
);
// data points to be added later (like points table)
$points = array(
array(
'idPlayer' => 1,
'Points' => 20,
),
array(
'idPlayer' => 2,
'Points' => 25,
),
array(
'idPlayer' => 3,
'Points' => 22,
),
);
$myArray = array();
foreach($players as $key => $value) {
foreach($points as $index => $element) {
// if this particular id matches the record inside points table then merge
if($value['idPlayer'] == $element['idPlayer']) {
$myArray[] = array('idPlayer' => $value['idPlayer'], 'namePlayer' => $value['namePlayer'], 'Points' => $element['Points']);
}
}
}
Should output something like: (can be used in a tabular data)
Array
(
[0] => Array
(
[idPlayer] => 1
[namePlayer] => John
[Points] => 20
)
[1] => Array
(
[idPlayer] => 2
[namePlayer] => Sam
[Points] => 25
)
[2] => Array
(
[idPlayer] => 3
[namePlayer] => Ben
[Points] => 22
)
)
Use the idPlayer as index:
$players = [
1 => [
'namePlayer' => 'John',
'points' => 20,
],
5 => [
'namePlayer' => 'Seth',
'points' => 25,
],
13 => [
'namePlayer' => 'Ben',
'points' => 35,
],
];
var_dump($players);
http://codepad.viper-7.com/nSXmZF
In php <5.4 use array() instead of [] constructor.

Subtract row values in Array2 from specific row values in Array1

I would like to subtract the quantity of $array2 from the stocks of $array1.
$array1= ([product_id]=>4, [stocks]=>20)
$array2= ([product_id]=>4, [quantity]=>3)
So that would be:
$array1= ([0]=> 4, [1] => 20);
$array2= ([0]=> 4, [1] => 3);
And then the output should be:
$array1= ([0]=> 4, [1] => 17);
Your array structure looks slightly different with multiple records, the code works out like this in an ugly manner. I'm assuming you're talking about something like this:
$array1 = array(
0=>array('product_id'=>4, 'stocks'=>20),
1=>array('product_id'=>5, 'stocks'=>60));
$array2 = array(
0=>array('product_id'=>4, 'quantity'=>3)
1=>array('product_id'=>5, 'quantity'=>30));
...It's a multi-dimensional array (typical for records pulled from a database).
foreach($array1 as $key=>$value){
foreach($array2 as $key2=>$value2) {
if($value['product_id']==$value2['product_id']){
$value['stocks'] -= $value2['quantity'];
//optimization to avoid searching this again.
unset($array2[$key]);
}
}}
With what you have given the following will do what you are asking for:
if($array1['product_id'] == $array2['product_id']) {
$array1['stocks'] -= $array2['quantity'];
}
If you need to loop through a bigger array then what I have given is only part of the larger puzzle.
Jesse's answer wasn't tested and will not provide the desired output because the "stocks" array wasn't being modified -- a copy of the array was being modified in the loop -- so if you try to print the result to screen, there would be no change.
To modify by reference, use & just before the value variable in the first loop.
Also the unset() key must come from the inner loop to be accurate.
Additionally, if the "sales" "product_id"s are unique, then breaking the inner loop upon matching will improve performance. (This is how array_search() works.)
Code: (Demo)
$stocks = [
['product_id'=>2, 'stocks'=>50],
['product_id'=>3, 'stocks'=>100],
['product_id'=>4, 'stocks'=>20],
['product_id'=>5, 'stocks'=>60]
];
$sales = [
['product_id'=>4, 'quantity'=>3],
['product_id'=>5, 'quantity'=>30]
];
foreach ($stocks as &$row) { // modify by reference
foreach ($sales as $k => $row2) { // search for product_id match
if ($row['product_id'] == $row2['product_id']) {
$row['stocks'] -= $row2['quantity']; // subtract
unset($sales[$k]); // eliminate match from lookup array
break; // assuming $sales['product_id'] values are unique
}
}
}
var_export($stocks);
Output:
array (
0 =>
array (
'product_id' => 2,
'stocks' => 50,
),
1 =>
array (
'product_id' => 3,
'stocks' => 100,
),
2 =>
array (
'product_id' => 4,
'stocks' => 17,
),
3 =>
array (
'product_id' => 5,
'stocks' => 30,
),
)
Alternatively, you can converted the sales array into a flattened, product_id-keyed array to serve as a lookup.
Code: (Demo)
$keyed = array_column($sales, 'quantity', 'product_id');
var_export($keyed);
echo "\n---\n";
foreach ($stocks as &$row) { // modify by reference
if (isset($keyed[$row['product_id']])) { // search for product_id match
$row['stocks'] -= $keyed[$row['product_id']]; // subtract
}
}
var_export($stocks);
Output:
array (
4 => 3,
5 => 30,
)
---
array (
0 =>
array (
'product_id' => 2,
'stocks' => 50,
),
1 =>
array (
'product_id' => 3,
'stocks' => 100,
),
2 =>
array (
'product_id' => 4,
'stocks' => 17,
),
3 =>
array (
'product_id' => 5,
'stocks' => 30,
),
)

PHP - Reorder array to match the order of another array

I have 1 array that has the right values that I need but it is out of order. I then have another array with the same keys and it is in the right order but the values are not what I need.
Here is my first array with the correct values but is out of order:
Array
(
[countTotal] => 7268
[zip] =>
[yearName] =>
[countZipRadius] =>
[Acura] => 1334
[Cadillac] => 511
[Ford] => 5423
)
Here is my second array with the right order but the wrong values:
Array
(
[countZipRadius] => 0
[zip] => 1
[yearName] => 2
[Acura] => 3
[Cadillac] => 4
[Ford] => 5
[countTotal] => 6
)
I am trying to figure out a way to create a new array with the right values from array 1 but that is in the order of array 2.
I have been playing with it for awhile and cannot seem to get it.
Any help would be great.
Thanks!
$c = array();
foreach (array_keys($b) as $k) {
$c[k] = $a[k];
}
You could use php's array_multisort function:
$original = array(
'countTotal' => 7268,
'zip' => '',
'yearName' => '',
'countZipRadius' => '',
'Acura' => 1334,
'Cadillac' => 511,
'Ford' => 5423,
);
$right = array(
'countZipRadius' => 0,
'zip' => 1,
'yearName' => 2,
'Acura' => 3,
'Cadilac' => 4,
'Ford' => 5,
'countTotal' => 6
);
//make sure both arrays are in the same order
ksort($original);
ksort($right);
array_multisort($right, $original);
print_r($original);
When you give it two arrays with the same number of elements it sorts both arrays, based on the order of the first array - in this case the 0, 1, 2, 3, etc. values in $right
Create a New Array (Array C)
Use a FOR loop to go through Array B
For each value in Array B, get the value with the same key from Array A and set Array C append those values to Array C. This will put them in the correct order in C.
Using scones' method:
$original = array(
'countTotal' => 7268,
'zip' => '',
'yearName' => '',
'countZipRadius' => '',
'Acura' => 1334,
'Cadillac' => 511,
'Ford' => 5423,
);
$right = array(
'countZipRadius' => 0,
'zip' => 1,
'yearName' => 2,
'Acura' => 3,
'Cadilac' => 4,
'Ford' => 5,
'countTotal' => 6
);
foreach ($right as $key => $value) {
$new[$key] = $original[$key];
}
print_r($new);
$array = array('a' => 100, 'b' => '5');
$newArray = array_combine(array_keys($array), range(0, count($array) - 1));
var_dump($newArray);

Categories