PHP Array Search and Delete - php

I have two array:
Array 1:
Array ( [0] => Array ( [id] => et1 [supplier_id] => 4 [supplier_product_code] => 00054X [is_active] => 1 )
[1] => Array ( [id] => et2 [supplier_id] => 4 [supplier_product_code] => 000558 [is_active] => 1 )
[2] => Array ( [id] => et3 [supplier_id] => 5 [supplier_product_code] => 00054X [is_active] => 1 ));
Array 2:
Array ( [0] => Array ([id] => et1 [same_sku] => et3);
I need to delete all the same_skus in array1 from array2.
So from my result array I need array1 to be:
Array ( [0] => Array ( [id] => et1 [supplier_id] => 4 [supplier_product_code] => 00054X [is_active] => 1 )
[1] => Array ( [id] => et2 [supplier_id] => 4 [supplier_product_code] => 000558 [is_active] => 1 ));
Code that I have right now does not work.
public function search_array($array, $val)
{
foreach ($array as $key => $row)
{
if ($row['id'] === $val)
{
return $key;
}
}
}
foreach($array2->result() as $row)
{
$id = $row->id;
$same_sku = $row->same_sku;
$key = $this->search_array($array1, $id);
if(!empty($key))
{
$same_sku_key = $this->search_array($array1, $same_sku);
if(!empty($same_sku_key))
unset($array1[$same_sku_key]);
}
}

In the following code I have recreated the two arrays from your example. I then created a function that removes from a haystack array (array1) all of the sub arrays that have an "id" that matches the value of "same_sku" within a needle array (array2). The final line echos the result array.
EDIT
I have modified the original answer to pass the array values by reference and unset the unwanted sub arrays, instead of passing by value, looping, and returning another array. This should resolve the memory issue, as well as the other issue mentioned in your comment.
$array1 = array(
array(
'id' => 'et1',
'supplier_id' => '4',
'supplier_product_code' => '00054X',
'is_active' => '1'
),
array(
'id' => 'et2',
'supplier_id' => '4',
'supplier_product_code' => '000558',
'is_active' => '1'
),
array(
'id' => 'et3',
'supplier_id' => '5',
'supplier_product_code' => '00054X',
'is_active' => '1'
),
array(
'id' => 'et4',
'supplier_id' => '5',
'supplier_product_code' => '00054X',
'is_active' => '1'
)
);
$array2 = array(
array(
'id' => 'et1',
'same_sku' => 'et3'
),
array(
'id' => 'et2',
'same_sku' => 'et4'
)
);
function remove_same_sku(&$haystack, &$needles){
foreach($needles as $needle){
foreach($haystack as $key => $val){
if($val['id'] === $needle['same_sku']){
unset($haystack[$key]);
}
}
}
}
remove_same_sku($array1, $array2);
echo print_r($array1);

Related

How to get Php multidimensional array same key’s same value’s related total in new array?

Php multidimensional array same key’s same value’s related total in
new array. I have an array of following mentioned. i need new array
as total qty of same item_id. anyone can help would be appreciate.
My Original Array is as following
Array
(
[a] => Array
(
[item] => Array
(
[item_id] => 1
)
[qty] => 0
),
[b] => Array
(
[item] => Array
(
[item_id] => 2
)
[qty] => 35
),
[c] => Array
(
[item] => Array
(
[item_id] => 2
)
[qty] => 15
),
[e] => Array
(
[item] => Array
(
[item_id] => 3
)
[qty] => 20
),
);
I want array Output like following :
Array(
[0] => Array (
[item_id] => 1,
[item_total_qty] => 0,
)
[1] => Array (
[item_id] => 2,
[item_total_qty] => 50,
)
[2] => Array (
[item_id] => 3,
[item_total_qty] => 20,
)
);
Hope it help
$arrays = array(
'a' => array(
'item' => array(
'item_id' => 1
),
'qty' => 0
),
'b' => array(
'item' => array(
'item_id' => 2
),
'qty' => 35
),
'c' => array(
'item' => array(
'item_id' => 2
),
'qty' => 15
),
'd' => array(
'item' => array(
'item_id' => 3
),
'qty' => 20
)
);
$result = array();
foreach ($arrays as $key => $array) {
if (is_array($result) && !empty($result)) {
foreach ($result as $key => $r) {
if ($r['item_id'] == $array['item']['item_id']) {
$result[$key]['item_total_qty'] += $array['qty'];
continue 2;
}
}
$result[] = array(
'item_id' => $array['item']['item_id'],
'item_total_qty' => $array['qty']);
} else {
$result[] = array(
'item_id' => $array['item']['item_id'],
'item_total_qty' => $array['qty']);
}
}
Simple foreach on your original table:
$sorted = array();
foreach ($original as $item) {
$id = $item['item']['item_id'];
$sorted[$id]['item_total_qty'] = $sorted[$id] ? $sorted[$id] + $item['qty'] : item['qty'];
$sorted[$id]['item_id'] = $id;
}
$sorted = array_values($sorted);

PHP - Merge 2 multidimensional array based on value

Currently, I have 2 multidimensional array and I'm looking to combine them into one giant array where the value's name in array 1 matches the value's name in array 2.
The array's look as followed...
Array1
(
[0] => Array
(
[id] => 1
[name] => test1
[desc] => test_desc
[quantity] => 3
)
[1] => Array
(
[id] => 2
[name] => test2
[desc] => test_desc
[quantity] => 33
)
)
Array2
(
[0] => Array
(
[holder] => 'John'
[name] => test1
[desc] => test_desc
[location] => ATL
)
[1] => Array
(
[holder] => 'Jackie'
[name] => test3
[desc] => test_desc
[location] => SF
)
)
I'm looking to merge the arrays where the 'name' column in array1 matches in array2 and also combine the columns in array's 1 & 2 into the final array. This should look like...
FinalArray
(
[0] => Array
(
[id] => 1
[holder] => 'John'
[name] => test1
[desc] => test_desc
[location] => ATL
[quantity] => 3
)
[1] => Array
(
[holder] => 'Jackie'
[name] => test3
[desc] => test_desc
[location] => SF
)
[2] => Array
(
[id] => 2
[name] => test2
[desc] => test_desc
[quantity] => 33
)
)
Where the "test1" combines the different columns across the 2 arrays into a new array inside the "FinalArray". I've tried researching some ideas with array_merge and array_merge_recursive but I'm not entirely sure if I'm going in the correct direction. Thanks in advance.
Try like this
$array1=[['id' => 1,'name' => 'test1','desc' => 'test_desc','quantity' => 3],
['id' => 2,'name' => 'test2','desc' => 'test_desc','quantity' => 33]];
$array2=[['holder' => 'John','name' => 'test1','desc' => 'test_desc','location' => 'ATL'],
['holder' => 'Jackie','name' => 'test3','desc' => 'test_desc','location' => 'SF']];
$final=[];
foreach ($array1 as $key1=>$data1){
foreach ($array2 as $key2=>$data2){
if($data1['name']==$data2['name']){
$final[]=$data1+$data2;
unset($array1[$key1]);
unset($array2[$key2]);
}
}
}
if(!empty($array1)){
foreach ($array1 as $value){
$final[]=$value;
}
}
if(!empty($array2)){
foreach ($array2 as $value){
$final[]=$value;
}
}
It will give output as
One more solution
function merge_by_name(array $arr1, array $arr2) {
$result = [];
foreach ($arr1 as $value) {
$key = array_search($value['name'], array_column($arr2, 'name'));
if($key !== false) {
$result[] = array_merge($value, $arr2[$key]);
unset($arr2[$key]);
} else {
$result[] = $value;
}
}
$result = array_merge($result, $arr2);
return $result;
}
Test
$arr1 = [
[
'id' => 1,
'name' => 'test1',
'desc' => 'test_desc',
'quantity' => 3
],
[
'id' => 2,
'name' => 'test2',
'desc' => 'test_desc',
'quantity' => 33
],
];
$arr2 = [
[
'holder' => 'John',
'name' => 'test1',
'desc' => 'test_desc',
'location' => 'ATL'
],
[
'holder' => 'Jackie',
'name' => 'test3',
'desc' => 'test_desc',
'location' => 'SF'
],
];
var_export(merge_by_name($arr1, $arr2));
Result
array (
0 =>
array (
'id' => 1,
'name' => 'test1',
'desc' => 'test_desc',
'quantity' => 3,
'holder' => 'John',
'location' => 'ATL',
),
1 =>
array (
'id' => 2,
'name' => 'test2',
'desc' => 'test_desc',
'quantity' => 33,
),
2 =>
array (
'holder' => 'Jackie',
'name' => 'test3',
'desc' => 'test_desc',
'location' => 'SF',
),
)

How to convert a recursive multidimensional array to a straight multidimensional array in PHP?

I have search for a solution for this but couldn't find anything giving me a "straight" multidimensional array back. Flatten is probably not the solution as long as i want to preserve the original sub structure?
In additional i want to summarize qty when the key is repeating.
This is my original array:
Array
(
[60002] => Array
(
[50001] => Array
(
[50002] => Array
(
[10001] => Array
(
[flag] => B
[qty] => 1
)
[10002] => Array
(
[flag] => B
[qty] => 1
)
[10003] => Array
(
[flag] => B
[qty] => 2
)
[flag] => M
[qty] => 1
)
[flag] => M
[qty] => 1
)
[flag] => G
[qty] => 1
)
[10001] => Array
(
[flag] => B
[qty] => 1
)
)
What i basically want is to create a new array looking like this:
Array
(
[10001] => Array
(
[flag] => B
[qty] => 2
)
[10002] => Array
(
[flag] => B
[qty] => 1
)
[10003] => Array
(
[flag] => B
[qty] => 2
)
[50001] => Array
(
[flag] => M
[qty] => 1
)
[50002] => Array
(
[flag] => M
[qty] => 1
)
[60002] => Array
(
[flag] => G
[qty] => 1
)
)
This is tested.
The key is intval().
$value['qty'] += intval($newArray[$key]['qty']);
If the [$key]['qty'] does not exist the intval() will return a zero. This is much faster than using an if else to check if a [$key]['qty'] already exists.
The only possible problem I could anticipate is if the Flag value is different when the key value is the same:
[10001] => Array(
[flag] => M
[qty] => 1
),
[10001] => Array(
[flag] => B
[qty] => 1
)
When this is an issue I resolve the priority with a logic table in an array.
$priority['M']['B'] = 'M'
$priority['B']['M'] = 'M'
$priority['']['M'] = 'M'
$priority['M'][''] = 'M'
$priority['B'][''] = 'B'
$priority['B'][''] = 'B'
settype($newArray[$key]['flag'],'string');
[$newArray[$key]['flag'] = $priority[$value['flag']][$newArray[$key]['flag']]
Data:
$array = array('60002' => Array('50001' => Array('50002' => Array('10001' => Array('flag' => 'B','qty' => 1),'10002' => Array('flag' => 'B','qty' => 1),'10003' => Array('flag' => 'B','qty' => 2),'flag' => 'M','qty' => 1),'flag' => 'M','qty' => 1),'flag' => 'G','qty' => 1),'10001' => Array('flag' => 'B','qty' => 1));
PHP
$newArray = array();
getValues($data);
function getValues($array){
global $newArray;
foreach ($array as $key => $value){
if(is_numeric($value['qty'])) {
$value['qty'] += intval($newArray[$key]['qty']);
$newArray[$key] = array('flag'=>$value['flag'],'qty'=>$value['qty']);
}
if (gettype($value) != 'array'){return;}
getValues($value);
}
}
ksort($newArray);
var_export($newArray);
Result:
array (
10001 =>
array (
'flag' => 'B',
'qty' => 2,
),
10002 =>
array (
'flag' => 'B',
'qty' => 1,
),
10003 =>
array (
'flag' => 'B',
'qty' => 2,
),
50001 =>
array (
'flag' => 'M',
'qty' => 1,
),
50002 =>
array (
'flag' => 'M',
'qty' => 1,
),
60002 =>
array (
'flag' => 'G',
'qty' => 1,
),
)
This seemed to work:
function extractArray(array $source, array &$destination, $originalIndex)
{
foreach($source as $index => $value)
{
if(is_array($value))
extractArray($value, $destination, $index);
else
$destination[$originalIndex][$index] = $value;
}
}
$test = array(
60002 => array
(
50001 => array
(
50002 => array
(
10001 => array
(
'flag' => 'B',
'qty' => 1
),
10002 => array
(
'flag' => 'B',
'qty' => 1
),
10003 => array
(
'flag' => 'B',
'qty' => 2
),
'flag' => 'M',
'qty' => 1
),
'flag' => 'M',
'qty' => 1
),
'flag' => 'G',
'qty' => 1
),
10001 => array
(
'flag' => 'B',
'qty' => 1
)
);
$new = array();
foreach($test as $index => $value)
extractArray($value, $new, $index);
var_dump($new);
die();
You can use a recursive approach to iterate over all levels of the array. For each item you check that it is an array and if it has any of the keys you want checked, add the array consisting of the found attributes.
function flattenArray($array, $keysToCheck) {
$result = array();
foreach($array as $item) {
// check if the current array item is a candidate to
// be added to the flattened array
if(is_array($item)) {
$foundAttributes = array();
foreach($item as $key=>$value) {
if(in_array($key, $keysToCheck) {
$foundAttributes[$key] = $value;
}
}
// we found at least one matching attribute
if(count($foundAttributes)) {
array_push($result, $foundAttributes);
}
// recursively go to the next level and merge the results from there
$result = array_merge($result, flattenArray($item, $keysToCheck);
}
}
return $result;
}
// usage example
$flattenedArray = flattenArray($originalArray, array('flag', 'qty'));
The above solution allows you to customise it for other type of objects, by passing different $keysToCheck arguments to the function.
If you also need the flattened array sorted, you can use usort() to achieve this.
Please pardon any syntax errors, I don't have a PHP interpreter at hand.

PHP Replace Array Values

I have 2 multidimensional arrays that I am working with:
$arr1 =
Array
([type] => characters
[version] => 5.6.7.8
[data] => Array
([Char1] => Array
([id] => 1
[name] =>Char1
[title] =>Example
[tags] => Array
([0] => DPS
[1] => Support))
[Char2] => Array
([id] => 2
[name] =>Char2
[title] =>Example
[tags] => Array
([0] => Tank
[1] => N/A)
)
)
etc...
$arr2=
Array
([games] => Array
([gameId] => 123
[gameType => Match
[char_id] => 1
[stats] => Array
([damage] => 55555
[kills] => 5)
)
([gameId] => 157
[gameType => Match
[char_id] => 2
[stats] => Array
([damage] => 12642
[kills] => 9)
)
etc...
Basically, I need almost all the data in $arr2... but only the Char name from $arr1. How could I merge or add the $arr1['name'] key=>value into $arr2 where $arr1['id'] is equal to $arr2['char_id'] as the "id" field of each array is the same number.
I've attempted using array_merge and array_replace, but I haven't come up with any working solutions. This is also all data that I am receiving from a 3rd party, so I have no control on initial array setup.
Thanks for any help or suggestions!
Actually, this is quite straighforward. (I don't think there a built-in function that does this.)
Loop $arr2 and under it loop also $arr1. While under loop, just add a condition that if both ID's match, add that particular name to $arr2. (And use some referencing & on $arr2)
Consider this example:
// your data
$arr1 = array(
'type' => 'characters',
'version' => '5.6.7.8',
'data' => array(
'Char1' => array(
'id' => 1,
'name' => 'Char1',
'title' => 'Example',
'tags' => array('DPS', 'Support'),
),
'Char2' => array(
'id' => 2,
'name' => 'Char2',
'title' => 'Example',
'tags' => array('Tank', 'N/A'),
),
),
);
$arr2 = array(
'games' => array(
array(
'gameId' => 123,
'gameType' => 'Match',
'char_id' => 1,
'stats' => array('damage' => 55555, 'kills' => 5),
),
array(
'gameId' => 157,
'gameType' => 'Match',
'char_id' => 2,
'stats' => array('damage' => 12642, 'kills' => 9),
),
),
);
foreach($arr2['games'] as &$value) {
$arr2_char_id = $value['char_id'];
// loop and check against the $arr1
foreach($arr1['data'] as $element) {
if($arr2_char_id == $element['id']) {
$value['name'] = $element['name'];
}
}
}
echo '<pre>';
print_r($arr2);
$arr2 should look now like this:
Array
(
[games] => Array
(
[0] => Array
(
[gameId] => 123
[gameType] => Match
[char_id] => 1
[stats] => Array
(
[damage] => 55555
[kills] => 5
)
[name] => Char1 // <-- name
)
[1] => Array
(
[gameId] => 157
[gameType] => Match
[char_id] => 2
[stats] => Array
(
[damage] => 12642
[kills] => 9
)
[name] => Char2 // <-- name
)
)
)
Iterate over $arr2 and add the data to it from the matching $arr1 array value:
$i = 0;
foreach($arr2['games'] as $arr2Game){
$id = $arr2Game['char_id'];
$arr2['games'][$i]['name'] = $arr1['data'][$id]['name'];
$i++;
}
Have not tested this code.
If I'm understanding you correctly, you want to add a name index to each of the arrays within the $arr2['games'] array.
foreach($arr2['games'] as $key => $innerArray)
{
$arr2['games'][$key]['name'] = $arr1['data']['Char'.$innerArray['char_id']]['name'];
}

Merge arrays (PHP)

How combine arrays in this way?
source:
Array
(
[0] => Array
(
[id] => 3
[title] => book
[tval] => 10000
)
[1] => Array
(
[id] => 3
[title] => book
[tval] => 1700
)
[3] => Array
(
[id] => 27
[title] => fruit
[tval] => 3000
)
.......
)
result:
Array
(
[0] => Array
(
[id] => 3
[title] => book
[tval] => 10000,1700
)
[1] => Array
(
[id] => 27
[title] => fruit
[tval] => 3000
)
.......
)
please help to solve this problem,
thanks!!!
sorry for bad english(
This should work:
$result = array();
foreach($array as $elem) {
$key = $elem['id'];
if (isset($result[$key])) {
$result[$key]['tval'] .= ',' . $elem['tval'];
} else {
$result[$key] = $elem;
}
}
This basically groups elements by id, concatenating tvals (separated by ,).
Simply building slightly on user576875's method:
$a = array ( 0 => array ( 'id' => 3,
'title' => 'book',
'tval' => 10000
),
1 => array ( 'id' => 3,
'title' => 'book',
'tval' => 1700
),
3 => array ( 'id' => 27,
'bcalias' => 'fruit',
'tval' => 3000
)
);
$result = array();
foreach ($a as $elem) {
$key = $elem['id'];
if (isset($result[$key])) {
$result[$key]['tval'] .= ',' . $elem['tval'];
} else {
$result[$key] = $elem;
}
}
$result = array_merge($result);
var_dump($result);
gives a result of:
array
0 =>
array
'id' => int 3
'title' => string 'book' (length=4)
'tval' => string '10000,1700' (length=10)
1 =>
array
'id' => int 27
'bcalias' => string 'fruit' (length=5)
'tval' => int 3000
The only real difference is the array_merge() to reset the keys

Categories