I got multidimensional array. From each subarray, I would like to remove / unset values with index 1. My array $data.
Array
(
[3463] => Array
(
[0] => 1
[1] => 2014
[context] => 'aaa'
)
[3563] => Array
(
[0] => 12
[1] => 2014
[context] => 'aaa'
)
[2421] => Array
(
[0] => 5
[1] => 2014
[context] => 'zzz'
)
)
I would like to remove every element with index '1' from subarrays. Desired output is:
Array
(
[3463] => Array
(
[0] => 1
[context] => 'aaa'
)
[3563] => Array
(
[0] => 12
[context] => 'aaa'
)
[2421] => Array
(
[0] => 5
[context] => 'zzz'
)
)
Why this does not work?
foreach ($data as $subArr) {
foreach ($subArr as $key => $value) {
if ($key == '1') {
unset($subArr[$key]);
}
}
}
I'm sorry if this problem is trivial for you guys.
easy way!?
you can do this just with one foreach!
foreach ($data as $key => $subArr) {
unset($subArr['1']);
$data[$key] = $subArr;
}
you are making changes in subarray instead of main one try this may help
foreach ($data as $key => $subArr) {
unset($data[$key][1]);
}
It does not work because $subArr from the outer foreach contains copies of the values of $data and the inner foreach modifies these copies, leaving $data not touched.
You can fix that by telling PHP to make $subArr references to the original values stored in $data:
foreach ($data as &$subArr) {
foreach ($subArr as $key => $value) {
if ($key == '1') {
unset($subArr[$key]);
}
}
}
Another option is to use function array_map(). It uses a callback function that can inspect (and modify) each value of $data and it returns a new array.
$clean = array_map(
function (array $elem) {
unset($elem['1']); // modify $elem
return $elem; // and return it to be put into the result
},
$data
);
print_r($clean);
try this:
<?php
$data = Array
(
'3463' => Array
(
'0' => 1,
'1' => 2014,
'context' => 'aaa'
),
'3563' => Array
(
'0' => 12,
'1' => 2014,
'context' => 'aaa'
),
'2421' => Array
(
'0' => 5,
'1' => 2014,
'context' => 'zzz'
)
);
foreach ($data as $k=>$subArr) {
foreach ($subArr as $key => $value) {
if ($key == '1') {
unset($data[$k][$key]);
}
}
}
print_r($data);// display the output
Related
I have a multidimensional array and am trying to group them according to the value in a specific column.
I'm trying to group them by level, but I won't actually know the level beforehand. So, it's not like I can put it in a for loop and say while $i < 7, because I won't know that 7 is the maximum value for the level key, and frankly, I'm not sure that's how I would need to do it even if I did.
[
['cust' => 'XT8900', 'type' => 'standard', 'level' => 1],
['cust' => 'XT8944', 'type' => 'standard', 'level' => 1],
['cust' => 'XT8922', 'type' => 'premier', 'level' => 3],
['cust' => 'XT8816', 'type' => 'permier', 'level' => 3],
['cust' => 'XT7434', 'type' => 'standard', 'level' => 7],
]
Desired result:
Array (
[1] => Array (
[0] => Array (
[cust] => XT8900
[type] => standard
)
[1] => Array (
[cust] => XT8944
[type] => standard
)
)
[3] => Array (
[2] => Array (
[cust] => XT8922
[type] => premier
)
[3] => Array (
[cust] => XT8816
[type] => permier
)
)
[7] => Array (
[4] => Array (
[cust] => XT7434
[type] => standard
)
)
)
Best way, if you have control over building the initial array, is just set things up like that at the start as you add entries.
If not then build a temporary array to sort:
foreach ($input_arr as $key => &$entry) {
$level_arr[$entry['level']][$key] = $entry;
}
Leaves you with the form you wanted and everything referenced together.
Build the array like that in the first place though if at all possible.
You need to group them by level first
Use foreach to loop into array check if the level is the same with the previous item then group it with that array
$templevel=0;
$newkey=0;
$grouparr[$templevel]="";
foreach ($items as $key => $val) {
if ($templevel==$val['level']){
$grouparr[$templevel][$newkey]=$val;
} else {
$grouparr[$val['level']][$newkey]=$val;
}
$newkey++;
}
print($grouparr);
The output of print($grouparr); will display like the format you hoped for
You can also try to
print($grouparr[7]);
Will display
[7] => Array (
[4] => Array (
[cust] => XT7434
[type] => standard
)
)
Or
print($grouparr[3]);
Will display
[3] => Array (
[2] => Array (
[cust] => XT8922
[type] => premier
)
[3] => Array (
[cust] => XT8816
[type] => permier
)
)
Here is the solution I landed on for an identical problem, wrapped as a function:
function arraySort($input,$sortkey){
foreach ($input as $key=>$val) $output[$val[$sortkey]][]=$val;
return $output;
}
To sort $myarray by the key named "level" just do this:
$myArray = arraySort($myArray,'level');
Or if you didn't want it as a function, just for a one time use, this would create $myNewArray from $myArray grouped by the key 'level'
foreach ($myArray as $key=>$val) $myNewArray[$val['level']][]=$val;
function group_assoc($array, $key) {
$return = array();
foreach($array as $v) {
$return[$v[$key]][] = $v;
}
return $return;
}
//Group the requests by their account_id
$account_requests = group_assoc($requests, 'account_id');
$result = array();
foreach ($yourArrayList as $data) {
$id = $data['level'];
if (isset($result[$id])) {
$result[$id][] = $data;
} else {
$result[$id] = array($data);
}
}
Best ans.
$levels = array_unique(array_column($records, 'level'));
$data = array();
foreach($records as $key => $value){
$data[$levels[array_search($value['level'],$levels )]][] = $value ;
}
print_r($data);
To generate the question's exact desured output from the sample input, pull/pop the last value from each row, use that value as the first level grouping key. Then use the original first level index as the second level key. Then push the two remaining elements into the group's subset.
Code: (Demo)
$result = [];
foreach ($array as $key => $row) {
$result[array_pop($row)][$key] = $row;
}
var_export($result);
For functional style syntax, use array_reduce(). (Demo)
var_export(
array_reduce(
array_keys($array),
function($result, $key) use ($array) {
$result[array_pop($array[$key])][$key] = $array[$key];
return $result;
}
)
);
function _group_by($array,$key,$keyName)
{
$return = array();
foreach($array as $val) {
$return[$keyName.$val[$key]][] = $val;
}
return $return;
} //end of function
How can we find the count of duplicate elements in a multidimensional array,
I have an array like this:
Array
(
[0] => Array
(
[brti] => 29
)
[1] => Array
(
[voda] => 6
)
[2] => Array
(
[btel] => 8
)
[3] => Array
(
[btel] => 10
)
)
Question: How to simplify the structure of array, i mean can be counting the value if there is indicate that have same key ?
just like this:
Array
(
[0] => Array
(
[brti] => 29
)
[1] => Array
(
[voda] => 6
)
[2] => Array
(
[btel] => 18
)
)
So far, i've tried this way, but it didn't help me. My array is store in $test
$test = [sample array]
$count = array();
foreach ($test as $key => $value) {
foreach ($value as $k => $val) {
if (isset($count[$val])) {
++$count[$val];
} else {
$count[$value] = 1;
}
}
}
print_r($count);
<?php
$array = [
"0" => ["brti" => 29],
"1" => ["voda" => 6],
"2" => ["btel" => 8],
"3" => ["btel" => 10],
];
$final = array();
array_walk_recursive($array, function($item, $key) use (&$final){
$final[$key] = isset($final[$key]) ? $item + $final[$key] : $item;
});
print_r($final);
});
check demo
You can do it in very simple way,
$test = [];
foreach ($array as $value)
{
foreach ($value as $k => $v)
{
// $test[$k] = ($test[$k] ?? 0); // initialised if not php 7+
$test[$k] = (empty($test[$k]) ? 0: $test[$k]); // below php 7
$test[$k] += $v;
}
}
print_r($test);
Output:
Array
(
[brti] => 29
[voda] => 6
[btel] => 18
)
Working demo.
I have an array in PHP code below, and I want to convert this array to be grouped by data value. It's always hard to simplify arrays.
Original array:
Array
(
[0] => Array
(
[date] => 2017-08-22
[AAA] => 1231
)
[1] => Array
(
[date] => 2017-08-21
[AAA] => 1172
)
[2] => Array
(
[date] => 2017-08-20
[AAA] => 1125
)
[3] => Array
(
[date] => 2017-08-21
[BBB] => 251
)
[4] => Array
(
[date] => 2017-08-20
[BBB] => 21773
)
[5] => Array
(
[date] => 2017-08-22
[CCC] => 3750
)
[6] => Array
(
[date] => 2017-08-20
[CCC] => 321750
)
)
Below is my desired array:
Array
(
[2017-08-22] => Array
(
[AAA] => 1231
[CCC] => 3750
)
[2017-08-21] => Array
(
[AAA] => 1172
[BBB] => 251
)
[2017-08-20] => Array
(
[AAA] => 1125
[BBB] => 21773
[CCC] => 321750
)
)
It is also ok to have empty null value if the data doesn't exist. [BBB] => NULL for 2017-08-22.
Can anybody help? Thanks in advance...
A simple loop should do this..
$group = [];
foreach ($data as $item) {
if (!isset($group[$item['date']])) {
$group[$item['date']] = [];
}
foreach ($item as $key => $value) {
if ($key == 'date') continue;
$group[$item['date']][$key] = $value;
}
}
Here : this should do the work.
$dst_array = array();
foreach ($array as $outerval) {
foreach ($outerval as $key => $innerval) {
if ($key != 'date') {
$dst_array[$outerval['date']][$key] = $innerval;
}
}
}
It iterates through the array and then through the entries in each subarray. Any any that is not a date is assigned in the destination array in the subarray corresponding to its date and with its own current key.
I definitely wouldn't recommend any techniques that involve more than one loop -- this process can certainly be performed in a single loop.
If you like language construct iteration, use a foreach() loop: (Demo)
$result = [];
foreach ($array as $row) {
$date = $row['date'];
unset($row['date']);
$result[$date] = array_merge($result[$date] ?? [], $row);
}
var_export($result);
If you like to use functional programming and fewer global variables, use array_reduce(): (Demo)
var_export(
array_reduce(
$array,
function($accumulator, $row) {
$date = $row['date'];
unset($row['date']);
$accumulator[$date] = array_merge($accumulator[$date] ?? [], $row);
return $accumulator;
},
[]
)
);
These techniques unconditionally push data into the subarray with the key based on the date column value.
The above technique will work consistently even if the order of your subarray elements changes.
The ?? (null coalescing operator) is to ensure that array_merge() always has an array in the first parameter -- if processing the first occurrence of a given date, you simply merge the current iteration's data (what's left of it after unset() removes the date element) with an empty array.
I believe this solution will work for you:
<?php
$array = Array
(
0 => Array
(
'date' => '2017-08-22',
'AAA' => '1231',
),
1 => Array
(
'date' => '2017-08-21',
'AAA' => '1172',
),
2 => Array
(
'date' => '2017-08-20',
'AAA' => '1125'
),
3 => Array
(
'date' => '2017-08-21',
'BBB' => '251'
),
4 => Array
(
'date' => '2017-08-20',
'BBB' => '21773',
),
5 => Array
(
'date' => '2017-08-22',
'CCC' => '3750'
),
6 => Array
(
'date' => '2017-08-20',
'CCC' => '321750'
)
);
echo '<pre>';
$array1 = array('AAA' => null, 'BBB' => null, 'CCC' => null);
$array2 = array();
array_walk($array, function ($v) use (&$array2, $array1) {
$a = $v['date'];
if (!isset($array2[$a])) {
$array2[$a] = $array1;
}
unset($v['date']);
$array2[$a] = array_merge($array2[$a], $v);
});
print_r($array2);
Output
Array
(
[2017-08-22] => Array
(
[AAA] => 1231
[BBB] =>
[CCC] => 3750
)
[2017-08-21] => Array
(
[AAA] => 1172
[BBB] => 251
[CCC] =>
)
[2017-08-20] => Array
(
[AAA] => 1125
[BBB] => 21773
[CCC] => 321750
)
)
check output at: https://3v4l.org/NvLB8
Another approach (quick & dirty) making use of an arrays internal pointer:
$newArray = [];
foreach ($array as $childArray) {
$date = current($childArray);
$value = next($childArray); // this advances the internal pointer..
$key = key($childArray); // ..so that you get the correct key here
$newArray[$date][$key] = $value;
}
This of course only works with the given array structure.
Another perfect usage example for the PHP function array_reduce():
// The input array
$input = array(
0 => array(
'date' => '2017-08-22',
'AAA' => '1231',
),
// The rest of your array here...
);
$output = array_reduce(
$input,
function (array $carry, array $item) {
// Extract the date into a local variable for readability and speed
// It is used several times below
$date = $item['date'];
// Initialize the group for this date if it doesn't exist
if (! array_key_exists($date, $carry)) {
$carry[$date] = array();
}
// Remove the date from the item...
// ...and merge the rest into the group of this date
unset($item['date']);
$carry[$date] = array_merge($carry[$date], $item);
// Return the partial result
return $carry;
},
array()
);
The question is not clear. What is the expected result if one key (AAA f.e) is present on two or more dates? This answer keeps only the last value associated with it.
i have 2 arrays i want to display the final array as what are the array element in $displayArray only be displayed from the $firstArray
$firstArray = Array
(
[0] => Array
(
[Dis_id] => Dl-Dis1
[Dis_Desc] => Discount
[Dis_Per] => 7.500
[Dis_val] => 26.25
)
[1] => Array
(
[Dis_id] => Dl-Dis2
[Dis_Desc] => Discount
[Dis_Per] => 2.500
[Dis_val] => 8.13
)
)
$displayArray = Array
(
[0] => Array
(
[0] => Dis_id
[1] => Dis_val
)
)
i want the final output will be
$resultArray = Array
(
[0] => Array
(
[Dis_id] => Dl-Dis1
[Dis_val] => 26.25
)
[1] => Array
(
[Dis_id] => Dl-Dis2
[Dis_val] => 8.13
)
)
Both the $firstArray and the $DisplayArray are dynamic but the $displayArray should be one.
i dont know how to do give me any suggestion
First up, if $displayArray will never have more than one array, the answer is pretty simple. Start by popping the inner array, to get to the actual keys you will need:
$displayArray = array_pop($displayArray);//get keys
$resultArray = array();//this is the output array
foreach ($firstArray as $data)
{
$item = array();
foreach ($displayArray as $key)
$item[$key] = isset($data[$key]) ? $data[$key] : null;//make sure the key exists!
$resultArray[] = $item;
}
var_dump($resultArray);
This gives you what you need.
However, if $displayArray contains more than 1 sub-array, you'll need an additional loop
$resultArray = array();
foreach ($displayArray as $k => $keys)
{
$resultArray[$k] = array();//array for this particular sub-array
foreach ($firstArray as $data)
{
$item = array();
foreach ($keys as $key)
$item[$key] = isset($data[$key]) ? $data[$key] : null;
$resultArray[$k][] = $item;//add data-item
}
}
var_dump($resultArray);
the latter version can handle a display array like:
$displayArray = array(
array(
'Dis_id',
'Dis_val'
),
array(
'Dis_id',
'Dis_desc'
)
);
And it'll churn out a $resultArray that looks like this:
array(
array(
array(
'Dis_id' => 'foo',
'Dis_val' => 123
)
),
array(
array(
'Dis_id' => 'foo',
'Dis_desc' => 'foobar'
)
)
)
Job done
I have a multidimensional array and am trying to group them according to the value in a specific column.
I'm trying to group them by level, but I won't actually know the level beforehand. So, it's not like I can put it in a for loop and say while $i < 7, because I won't know that 7 is the maximum value for the level key, and frankly, I'm not sure that's how I would need to do it even if I did.
[
['cust' => 'XT8900', 'type' => 'standard', 'level' => 1],
['cust' => 'XT8944', 'type' => 'standard', 'level' => 1],
['cust' => 'XT8922', 'type' => 'premier', 'level' => 3],
['cust' => 'XT8816', 'type' => 'permier', 'level' => 3],
['cust' => 'XT7434', 'type' => 'standard', 'level' => 7],
]
Desired result:
Array (
[1] => Array (
[0] => Array (
[cust] => XT8900
[type] => standard
)
[1] => Array (
[cust] => XT8944
[type] => standard
)
)
[3] => Array (
[2] => Array (
[cust] => XT8922
[type] => premier
)
[3] => Array (
[cust] => XT8816
[type] => permier
)
)
[7] => Array (
[4] => Array (
[cust] => XT7434
[type] => standard
)
)
)
Best way, if you have control over building the initial array, is just set things up like that at the start as you add entries.
If not then build a temporary array to sort:
foreach ($input_arr as $key => &$entry) {
$level_arr[$entry['level']][$key] = $entry;
}
Leaves you with the form you wanted and everything referenced together.
Build the array like that in the first place though if at all possible.
You need to group them by level first
Use foreach to loop into array check if the level is the same with the previous item then group it with that array
$templevel=0;
$newkey=0;
$grouparr[$templevel]="";
foreach ($items as $key => $val) {
if ($templevel==$val['level']){
$grouparr[$templevel][$newkey]=$val;
} else {
$grouparr[$val['level']][$newkey]=$val;
}
$newkey++;
}
print($grouparr);
The output of print($grouparr); will display like the format you hoped for
You can also try to
print($grouparr[7]);
Will display
[7] => Array (
[4] => Array (
[cust] => XT7434
[type] => standard
)
)
Or
print($grouparr[3]);
Will display
[3] => Array (
[2] => Array (
[cust] => XT8922
[type] => premier
)
[3] => Array (
[cust] => XT8816
[type] => permier
)
)
Here is the solution I landed on for an identical problem, wrapped as a function:
function arraySort($input,$sortkey){
foreach ($input as $key=>$val) $output[$val[$sortkey]][]=$val;
return $output;
}
To sort $myarray by the key named "level" just do this:
$myArray = arraySort($myArray,'level');
Or if you didn't want it as a function, just for a one time use, this would create $myNewArray from $myArray grouped by the key 'level'
foreach ($myArray as $key=>$val) $myNewArray[$val['level']][]=$val;
function group_assoc($array, $key) {
$return = array();
foreach($array as $v) {
$return[$v[$key]][] = $v;
}
return $return;
}
//Group the requests by their account_id
$account_requests = group_assoc($requests, 'account_id');
$result = array();
foreach ($yourArrayList as $data) {
$id = $data['level'];
if (isset($result[$id])) {
$result[$id][] = $data;
} else {
$result[$id] = array($data);
}
}
Best ans.
$levels = array_unique(array_column($records, 'level'));
$data = array();
foreach($records as $key => $value){
$data[$levels[array_search($value['level'],$levels )]][] = $value ;
}
print_r($data);
To generate the question's exact desured output from the sample input, pull/pop the last value from each row, use that value as the first level grouping key. Then use the original first level index as the second level key. Then push the two remaining elements into the group's subset.
Code: (Demo)
$result = [];
foreach ($array as $key => $row) {
$result[array_pop($row)][$key] = $row;
}
var_export($result);
For functional style syntax, use array_reduce(). (Demo)
var_export(
array_reduce(
array_keys($array),
function($result, $key) use ($array) {
$result[array_pop($array[$key])][$key] = $array[$key];
return $result;
}
)
);
function _group_by($array,$key,$keyName)
{
$return = array();
foreach($array as $val) {
$return[$keyName.$val[$key]][] = $val;
}
return $return;
} //end of function