How to merge two arrays without adding another index - php

I was trying to add some numbers from two or more arrays to one array. My problem is, that it always adds another index.
Source arrays looks like this:
array(
(int) 0 => array(
'Sale' => array(
'id' => '1',
'market_id' => '1',
'product_ids' => '1,2,3,4,5,6,7,8',
'date_and_time' => '2014-12-28 00:00:00',
'money_spent' => '2344',
'points_given' => '213'
)
),
(int) 1 => array(
'Sale' => array(
'id' => '2',
'market_id' => '1',
'product_ids' => '44,3,32,23,12,32',
'date_and_time' => '2014-12-28 15:25:38',
'money_spent' => '123',
'points_given' => '2'
)
)
)
PHP code that im using to merge arrays and explode numbers from product_ids field
$sales=array();
foreach ($sales_detailed as $sale_detailed): {
$sale_detailed_ids=explode( ',', $sale_detailed['Sale']['product_ids'] );
array_push($sales, $sale_detailed_ids);
} endforeach;
The result is
array(
(int) 0 => array(
(int) 0 => '1',
(int) 1 => '2',
(int) 2 => '3',
(int) 3 => '4',
(int) 4 => '5',
(int) 5 => '6',
(int) 6 => '7',
(int) 7 => '8'
),
(int) 1 => array(
(int) 0 => '44',
(int) 1 => '3',
(int) 2 => '32',
(int) 3 => '23',
(int) 4 => '12',
(int) 5 => '32'
)
)
While i want it to look like this
array(
(int) 0 => array(
(int) 0 => '1',
(int) 1 => '2',
(int) 2 => '3',
(int) 3 => '4',
(int) 4 => '5',
(int) 5 => '6',
(int) 6 => '7',
(int) 7 => '8'
(int) 8 => '44',
(int) 9 => '3',
(int) 10 => '32',
(int) 11 => '23',
(int) 12 => '12',
(int) 13 => '32'
)
)

Well, you're just merging it wrong from my view of point. Make a foreach to loop through the comma-separated list and add it manually instead of pushing the whole array.
$sales=array();
foreach ($sales_detailed as $sale_detailed) {
$sale_detailed_ids = explode( ',', $sale_detailed['Sale']['product_ids'] );
foreach($sale_detailed_ids as $ids) {
$sales[] = $ids;
}
}
http://3v4l.org/hoaVF

You'll have to write some custom code to "skip" the first level of arrays, and merge only the second.
function mergeKeepIds($a, $b) {
$keys = array_unique(array_keys($a) + array_keys($b)); // Grab all the keys.
$result = [];
foreach ($keys as $key) {
$valueA = array_key_exists($key, $a) ? $a[$key] : [];
$valueB = array_key_exists($key, $b) ? $b[$key] : [];
$result[$key] = array_merge($valueA, $valueB);
}
return $result;
}

Use a variadic push technique to avoid writing a nested loop -- array_push() is most appropriate to use when you have more than one value to push into a declared array.
Code: (Demo)
$sales = [];
foreach ($sales_detailed as $sale_detailed) {
array_push($sales, ...explode(',', $sale_detailed['Sale']['product_ids']));
}
var_export($sales);

Related

OUTPUT Alone 1 key from the array

How to make if _from is Alone to _to --- to Select _Alone with the higher ID
Drop else from array
array (
0 =>
array (
'id' => '8',
'_from' => '2',
'_to' => '1',
'date' => '2018-10-15 15:51:07',
'message' => 'ccccccxxxxx',
'read' => '0',
'feedback' => '0',
'cnt' => '3',
),
1 =>
array (
'id' => '6',
'_from' => '1',
'_to' => '2',
'date' => '2018-10-15 15:47:01',
'message' => 'zzzzzzz1',
'read' => '1',
'feedback' => '0',
'cnt' => '1',
),
If you have small arrays, It is not a problem to run the algorithm with complexity O(n2). But for me better is less clear, but faster algorithm with complexity equals to O(2n)
$array = array(
array(
'id' => 12,
'_from' => 1,
'_to' => 2
),
array(
'id' => 13,
'_from' => 4,
'_to' => 2
),
array(
'id' => 14,
'_from' => 2,
'_to' => 1
),
);
$newArray = [];
foreach ($array as $item) {
$uniqueRecordKey = $item['_from'].'-'.$item['_to'];
$oppositeRecordKey = $item['_to'].'-'.$item['_from'];
//If exists record from the opposite and new ID is greater than previous put
if (isset($newArray[$oppositeRecordKey])) {
$newArray[$oppositeRecordKey] = $item;
continue; //Do not append to the end
}
$newArray[$uniqueRecordKey] = $item;
}
var_dump($newArray);
https://3v4l.org/0oL2d

Only show Unique ID greater than x seconds in PHP

I am trying to figure out how to only output unique IDs that are above 30 seconds in this array. to make it simple it just needs to grab the first value over 30 seconds for a unique ID.
$array = array(
0 => array(
'id' => '1',
'seconds' => '36'
),
1 => array(
'id' => '1',
'seconds' => '60'
),
2 => array(
'id' => '1',
'seconds' => '36'
),
3 => array(
'id' => '2',
'seconds' => '22'
),
4 => array(
'id' => '1',
'seconds' => '36'
),
5 => array(
'id' => '2',
'seconds' => '36'
),
6 => array(
'id' => '3',
'seconds' => '44'
),
7 => array(
'id' => '3',
'seconds' => '2'
),
8 => array(
'id' => '4',
'seconds' => '58'
),
9 => array(
'id' => '6',
'seconds' => '9'
),
10 => array(
'id' => '6',
'seconds' => '8'
));
Ideal result would look like this
$arrayResult = array(
0 => array(
'id' => '1',
'seconds' => '36'
),
1 => array(
'id' => '2',
'seconds' => '36'
),
2 => array(
'id' => '3',
'seconds' => '44'
),
3 => array(
'id' => '4',
'seconds' => '58'
));
Currently I can only get unique values for the ID's without having the seconds correlated with the 'id' field.
You can use array_reduce to iterate over the $array and extract only values that you want.
$array = array_reduce($array, function ($unique, $entry) {
extract($entry);
if (! isset($unique[$id]) && $seconds > 30) {
$unique[$id] = $entry;
}
return $unique;
}, []);
$array = array_values($array);
$final_array = array();
foreach($array as $val)
{
if($val['seconds'] > 30 && (!array_key_exists($val['id'], $final_array))){
$final_array[$val['id']] = $val;
}
}
echo "<pre>";
print_r($final_array);
echo "</pre>";
if you want to reset array keys then you can use
$final_array = array_values($final_array);
echo "<pre>";
print_r($final_array);
echo "</pre>";

PHP finding same record in array

I would like to detect same records and then change quantity of the one record and delete the others. For example, given the following array:
'Cart' => [
(int) 0 => [
'size' => '38',
'code' => '5',
'qn' => (int) 1
],
(int) 1 => [
'size' => '37',
'code' => '5',
'qn' => (int) 1
],
(int) 2 => [
'size' => '37',
'code' => '5',
'qn' => (int) 1
]
],
i would like to print:
'Cart' => [
(int) 0 => [
'size' => '38',
'code' => '5',
'qn' => (int) 1
],
(int) 1 => [
'size' => '37',
'code' => '5',
'qn' => (int) 2
]
],
It looks to me that you're trying to sum quantities (qn) on duplicate sizes (size) and codes (code). One way to achieve this is by looping through the array containing the cart items and building out a new array. I suggest reading about PHP arrays and array_key_exists to learn more as they're used below:
<?php
$arr = [
['size' => '38', 'code' => 5, 'qn' => 1],
['size' => '37', 'code' => 5, 'qn' => 1],
['size' => '37', 'code' => 5, 'qn' => 1],
['size' => '37', 'code' => 4, 'qn' => 1],
];
$newArr = [];
foreach ($arr as $value) {
$key = $value['size'] . ':' . $value['code'];
if (array_key_exists($key, $newArr)) {
$newArr[$key]['qn'] += $value['qn'];
continue;
}
$newArr[$key] = $value;
}
// Resets keys
$newArr = array_values($newArr);
print_r($newArr);
I dont know it is enough for your problem, but try function array_unique
Iterate your array and use array_diff on each subarray.
If the returned array doesn't contain neither size nor code, add the two qn
The function array_unique() works for single dimension array. To find unique elements from multi-dimension array, we need to do a little modification.
Try this:
$array = array_map("serialize", $array);
$output = array_map("unserialize", array_unique($array));
If you want to follow another approach, use this as a reference: Create multidimensional array unique
Please go through following code.
$result = [
0=> ['size' => '38',
'code' => '5',
'qn' => 1
],
1=> ['size' => '37',
'code' => '5',
'qn' => 1
],
2=> ['size' => '37',
'code' => '5',
'qn' => 1
]
];
$finalArr = [];
foreach($result as $k => $v) {
$flag = 0;
foreach($finalArr as $kc => $vc){
if($v['size']==$vc['size'] && $v['code']==$vc['code']){
$flag = 1;
$finalArr[$kc]['qn'] = $finalArr[$kc]['qn'] + 1;
break;
}
}
if($flag==0){
$finalArr[] =
[
'size' => $v['size'],
'code' => $v['code'],
'qn' => 1
];
}
}
echo "<pre>";
print_r($finalArr);
The code is tested against your question and i have explained the code. This gives you solution for any number of arrays and with similar array elements with quantity(qn) incremented as you wanted:
<?php
//Compare the 1st and 2nd array
//Compare the 2st and 3rd array
// and so on
function compare($arr1 = array(), $arr2 = array()) {
$result = array_diff($arr1, $arr2);
return $result;
}
$cart = array(
0 => array('size' => 38, 'code' => 5, 'qn' => 1),
1 => array('size' => 37, 'code' => 5, 'qn' => 1),
2 => array('size' => 37, 'code' => 5, 'qn' => 1),
);
$j = 1;
$cart_total_count = count($cart);//Gives the count of your cart
$final_cart = array();//Final array with qn incremented
for($i=0;$i<$cart_total_count; $i++) {
if (!empty($cart[$i+1])) {//If 2nd array is not present then stop the comparision
if (empty(compare($cart[$i], $cart[$i+1]))){
$j++;
$cart[$i]['qn'] = $j;
$final_cart = $cart[$i];
}
}
}var_dump($final_cart);
//Output
//1. If 2 array are same
//array(3) { ["size"]=> int(37) ["code"]=> int(5) ["qn"]=> int(2) }
//2. If no array are same
//array(0) { }?>

How to copy this portion of the array to a new array in php?

I have this php array X.
X= array(
'Parent' => array(
'title' => '123',
)
)
I have this php array Y.
Y = array(
'Parent' => array(
'id' => '16',
'title' => 'T1',
),
'Children' => array(
(int) 0 => array(
'id' => '8',
'serial_no' => '1',
),
(int) 1 => array(
'id' => '9',
'serial_no' => '2',
),
(int) 2 => array(
'id' => '14',
'serial_no' => '6',
)
)
)
I want to copy the Children of array Y to the parent of array X to form array Z such that it looks like this;
Z= array(
'Parent' => array(
'title' => '123',
)
'Children' => array(
(int) 0 => array(
'serial_no' => '1'
),
(int) 1 => array(
'serial_no' => '2'
),
(int) 2 => array(
'serial_no' => '6'
)
)
)
Please note that the id key-value pair was removed from the Children of array Y.
I wrote some code of my own.
$Z = array();
$i=0;
foreach($Y as $temp)
{
$Z['Children'][$i] = $temp['Children'][$i];
unset($Z['Children'][$i]['id'];
$i++;
}
$Z['Parent']=$temp['Parent'];
Unfortunately, there is an undefined index error. How can this be done in php? Forget about my code if there are better approaches.
Actually your approach works too, but you need to iterate over sub-array:
$Z = array();
$i=0;
foreach($Y['Children'] as $temp)
{
$Z['Children'][$i] = $temp;
unset($Z['Children'][$i]['id'];
$i++;
}
or what I may do:
$Z = $X;
$Z['Children'] = array();
foreach ( $Y['Children'] as $child ) {
$Z['Children'][] = array(
'serial_no' => $child['serial_no'],
);
}
You can do like.
$Z = array();
foreach($Y['Children'] as $temp)
{
$Z['Children'][] = array('serial_no' => $temp['serial_no']);
}
$Z['Parent']=$X['Parent'];

inserting an array

I have the following array that I want to insert into the table with the fields groupi_id, application_id and grant_id
the array is
array(
'ApplicationsGrant' => array(
'group_id' => array(
(int) 0 => '72',
(int) 1 => '72'
),
'application_id' => array(
(int) 0 => '1',
(int) 1 => '2'
),
'grant_id' => array(
(int) 0 => 56,
(int) 1 => 57
)
)
)
I want to insert the rows that every sub array goes with array key. so there will be 2 rows inserted in above case like this
insert into table (group_id. application_id, grant_id) Values (72, 1, 56);
insert into table (group_id. application_id, grant_id) Values (72, 2, 57);
howd I do that?
You can use Cake's Set::classicExtract() to pull out the values. I assume you know how to then save them to the DB.
http://book.cakephp.org/2.0/en/core-utility-libraries/set.html
In your case, something like (untested):
$result1 = Set::classicExtract($a, '{n}.{s}.{s}.0');
$result2 = Set::classicExtract($a, '{n}.{s}.{s}.1');
If you need the keys, you can extract those first:
$fields = Set::classicExtract($a, '{n}.{s}.{s}');
I have tried this one
$d = array(
'ApplicationsGrant' => array(
'group_id' => array(
(int) 0 => '72',
(int) 1 => '72'
),
'application_id' => array(
(int) 0 => '1',
(int) 1 => '2'
),
'grant_id' => array(
(int) 0 => 56,
(int) 1 => 57
)
)
);
for ($i=0; $i<count($d['ApplicationsGrant']['group_id']); $i++) {
echo $d['ApplicationsGrant']['group_id'][$i]."<br/>"; //outputs 72, 72
}

Categories