Group array by field and give total value - php

I'm trying to group the following array by 'label' to give a total value for each person.
Array
(
[0] => Array
(
[label] => John
[value] => 84
)
[1] => Array
(
[label] => Darren
[value] => 28
)
[2] => Array
(
[label] => John
[value] => 20
)
[3] => Array
(
[label] => Morgan
[value] => 20
)
[4] => Array
(
[label] => Hannah
[value] => 14
)
[5] => Array
(
[label] => Morgan
[value] => 14
)
[6] => Array
(
[label] => Darren
[value] => 10
)
)
This would be the end result:
Array
(
[0] => Array
(
[label] => John
[value] => 104
)
[1] => Array
(
[label] => Darren
[value] => 38
)
[2] => Array
(
[label] => Morgan
[value] => 34
)
[3] => Array
(
[label] => Hannah
[value] => 14
)
)
I'm assuming I need to use foreach to group the labels together but I'm stuck for the best way to do this.

I would do something like this (expecting your array in $array):
// output array
$newArray = array();
// loop over the input array
foreach($array as $entry) {
// loop over the output array
foreach($newArray as &$currentEntry) {
// check if there is a the current label
if($currentEntry['label'] == $entry['label']) {
// if so, add the value and continue (also parent)
$currentEntry['value'] += $entry['value'];
continue 2;
}
}
// if the current label wan't found, it will get here and add an entry
array_push($newArray,$entry);
}
print_r($newArray);

Try this:
<?php
$array = [
['label' => 'John',
'value' => '84'],
['label' => 'Darren',
'value' => '28'],
['label' => 'John',
'value' => '20'],
['label' => 'Morgan',
'value' => '20'],
['label' => 'Hannah',
'value' => '14'],
['label' => 'Morgan',
'value' => '14'],
['label' => 'Darren',
'value' => '10']
];
$final = [];
foreach ($array as $arr)
$final[$arr['label']] = isset($final[$arr['label']]) ? $final[$arr['label']] + $arr['value'] : $arr['value'];
$result = [];
foreach ($final as $label => $value)
$result[] = ['label' => $label, 'value' => $value];
print_r($result);
Output:
Array
(
[0] => Array
(
[label] => John
[value] => 104
)
[1] => Array
(
[label] => Darren
[value] => 38
)
[2] => Array
(
[label] => Morgan
[value] => 34
)
[3] => Array
(
[label] => Hannah
[value] => 14
)
)

Related

How to build tree structure from array in PHP

I have following table:
$arr = array(
array('id'=>100, 'year'=>2019, 'month'=>9, 'name'=>'a'),
array('id'=>101, 'year'=>2019, 'month'=>12, 'name'=>'b'),
array('id'=>102, 'year'=>2020, 'month'=>1, 'name'=>'c'),
array('id'=>103, 'year'=>2020, 'month'=>2, 'name'=>'d'),
);
With the code below
$tree = array();
foreach ($arr as $row) {
$tree[$row['year']] = array(
$row['month'] => array (
'id' => $row['id'],
'name' => $row['name'],
),
);
}
I would like to get following result - this structure as a tree:
Array
(
[2019] => Array
(
[9] => Array
(
[id] => 100
[name] => a
)
[12] => Array
(
[id] => 101
[name] => b
)
)
[2020] => Array
(
[1] => Array
(
[id] => 102
[name] => c
)
[2] => Array
(
[id] => 103
[name] => d
)
)
)
Unfortunately I get only following one with single "branches":
Array
(
[2019] => Array
(
[12] => Array
(
[id] => 101
[name] => b
)
)
[2020] => Array
(
[2] => Array
(
[id] => 103
[name] => d
)
)
)
What is missing here? why previous rows disappear from the structure?
As you want the year and month as the main indexes, you need to use both of these when adding the data into the $tree...
$tree = array();
foreach ($arr as $row) {
$tree[$row['year']][$row['month']] = [ 'id' => $row['id'],
'name' => $row['name']];
}
with your test data, this gives...
Array
(
[2019] => Array
(
[9] => Array
(
[id] => 100
[name] => a
)
[12] => Array
(
[id] => 101
[name] => b
)
)
[2020] => Array
(
[1] => Array
(
[id] => 102
[name] => c
)
[2] => Array
(
[id] => 103
[name] => d
)
)
)
You have mistake in key's names - bl_year, bl_month not exist:
foreach ($arr as $row) {
$tree[$row['year']] = array(
$row['month'] => array (
'id' => $row['id'],
'name' => $row['name'],
),
);
}

PHP - Array unique only using specific values

I have a PHP array that looks like this...
Array
(
[0] => Array
(
[id] => 1
[value] => 111
[date] => 'today'
)
[1] => Array
(
[id] => 2
[value] => 222
[date] => 'today'
)
[2] => Array
(
[id] => 3
[value] => 333
[date] => 'today'
)
[3] => Array
(
[id] => 1
[value] => 111
[date] => 'today'
)
[4] => Array
(
[id] => 5
[value] => 111
[date] => 'today'
)
)
If I use array_unique like this...
print_r(array_unique($array, SORT_REGULAR));
It removes the duplicate [3] which is correct, but I am looking for a way to ignore [id] and only match by [date] and [value] so that my output looks like this...
Array
(
[0] => Array
(
[id] => 1
[value] => 111
[date] => 'today'
)
[1] => Array
(
[id] => 2
[value] => 222
[date] => 'today'
)
[2] => Array
(
[id] => 3
[value] => 333
[date] => 'today'
)
)
array_reduce + array_values() solution:
$arr = [
['id' => 1, 'value' => 111, 'date'=> 'today'],
['id' => 2, 'value' => 222, 'date'=> 'today'],
['id' => 3, 'value' => 333, 'date'=> 'today'],
['id' => 1, 'value' => 111, 'date'=> 'today'],
['id' => 5, 'value' => 111, 'date'=> 'today']
];
$result = array_values(
array_reduce($arr, function($r, $a){
if (!isset($r[$a['value'] . $a['date']])) $r[$a['value'] . $a['date']] = $a;
return $r;
}, [])
);
print_r($result);
The output:
Array
(
[0] => Array
(
[id] => 1
[value] => 111
[date] => today
)
[1] => Array
(
[id] => 2
[value] => 222
[date] => today
)
[2] => Array
(
[id] => 3
[value] => 333
[date] => today
)
)
Iterate over your array and get a key as concatenation of 'date' and 'value' fields. If this key has already been found - skip array value:
$pairs = [];
$new_values = [];
foreach ($array as $item) {
$key = $item['date'] . $item['value'];
if (empty($pairs[$key])) {
$pairs[$key] = 1;
$new_values[] = $item;
}
}

array one format to another

I have one array in two format. I want to change array from
Array
(
[step_number] => 4
[app_id] => Array
(
[0] => 2
[1] => 3
)
[formdata] => Array
(
[0] => Array
(
[name] => app_id[]
[value] => 2
)
[1] => Array
(
[name] => app_id[]
[value] => 3
)
[2] => Array
(
[name] => fieldval[2][2][]
[value] => 1
)
[3] => Array
(
[name] => fieldval[3][3][]
[value] => 200
)
[4] => Array
(
[name] => fieldval[3][3][]
[value] => day
)
[5] => Array
(
[name] => title
[value] => new plan
)
[6] => Array
(
[name] => feature_plan
[value] => 3
)
[7] => Array
(
[name] => plan_type
[value] => free
)
[8] => Array
(
[name] => price
[value] =>
)
[9] => Array
(
[name] => sell_type
[value] => us
)
)
)
this format to
Array
(
[app_id] => Array
(
[0] => 2
[1] => 3
)
[fieldval] => Array
(
[2] => Array
(
[2] => Array
(
[0] => 1
)
)
[3] => Array
(
[3] => Array
(
[0] => 200
[1] => day
)
)
)
[title] => new plan
[feature_plan] => 3
[plan_type] => free
[price] =>
[sell_type] => us
)
these are are one array into two format. i have data in to first array format and i want to change that format to second array type format.
please tell me how i am trying this for 2 days but not succeed.
Here is a function you could use to produce that conversion:
function convert_formdata($input) {
$output = array();
foreach($input['formdata'] as $data) {
$keys = preg_split("#[\[\]]+#", $data['name']);
$value = $data['value'];
$target = &$output;
foreach($keys as $key) {
// Get index for "[]" reference
if ($key == '') $key = count($target);
// Create the key in the parent array if not there yet
if (!isset($target[$key])) $target[$key] = array();
// Move pointer one level down the hierarchy
$target = &$target[$key];
}
// Write the value at the pointer location
$target = $value;
}
return $output;
}
You would call it like this:
$output = convert_formdata($input);
See it run on eval.in for the given input. The output is:
array (
'app_id' =>
array (
0 => 2,
1 => 3,
),
'fieldval' =>
array (
2 =>
array (
2 =>
array (
0 => 1,
),
),
3 =>
array (
3 =>
array (
0 => 200,
1 => 'day',
),
),
),
'title' => 'new plan,',
'feature_plan' => 3,
'plan_type' => 'free',
'price' => NULL,
'sell_type' => 'us',
)

How to fetch array in correct order

How to fetch array in correct order ?
I am printing a array but it is not fetching in correct order.
I want that each track value contain array of date and array of
number respectively. please give a solution .Any help would be
highly appreciated.
My code for fetch array are:
<?php
foreach($posts as $post)
{
$array['track_value'][] = $post->track_value;
$array['track_value']['date'][] = $post->date;
$array['track_value']['num'][] = $post->num;
}
?>
From this i am getting wrong value like these:
<?php
Array (
[track_value] => Array
(
[0] => mobile
[date] => Array
(
[0] => 2015-08-23
[1] => 2015-08-24
[2] => 2015-08-23
[3] => 2015-08-24
[4] => 2015-08-22
[5] => 2015-08-23
[6] => 2015-08-24
)
[num] => Array
(
[0] => 1
[1] => 1
[2] => 1
[3] => 2
[4] => 1
[5] => 1
[6] => 1
)
[1] => mobile
[2] => laptop
[3] => laptop
[4] => pc
[5] => pc
[6] => pc
)
)
?>
The output should be like:
<?php
Array (
[track_value] => Array
(
[0] => mobile
Array
(
[date] => Array
(
[0] => 2015-08-23
[1] => 2015-08-24
)
[num] => Array
(
[0] => 1
[1] => 1
)
)
[1] => laptop
Array
(
[date] => Array
(
[0] => 2015-08-23
[1] => 2015-08-24
)
[num] => Array
(
[0] => 1
[1] => 2
)
)
[2] => pc
Array
(
[date] => Array
(
[0] => 2015-08-23
[1] => 2015-08-24
[2] => 2015-08-23
)
[num] => Array
(
[0] => 1
[1] => 1
[2] => 1
)
)
)
)
?>
I'm not sure what you are trying to do, but maybe this will help you on the way:
foreach($posts as $post)
{
$array['track_value'][$post->track_value]['date'][] = $post->date;
$array['track_value'][$post->track_value]['num'][] = $post->num;
}
This will give you an output like:
Array(
'track_value' => Array(
'mobile' => Array(
'date' => Array(
0 => '2015-08-25',
1 => '2015'08'26',
),
'num' => Array(
0 => 1337,
1 => 13337,
),
),
'pc' => ...
),
)
Try this:
$arr = [];
foreach($posts as $key => $val)
$arr['track_value'][$val->track_value][] = ['date' => $val->date, 'num' => $val->num];
}
print_r($arr);
Try this:
$tracks = [];
foreach($posts as $k1 as $v1) {
if (is_array($value)){
foreach ($value as $k2 => $v2) {
$tracks[$k1][$k2] = $v2;
}
}
$tracks[$k1] = $v1;
}

Altering multidimensional array

I have a large multidimensional array and I basically want to drop the first level of arrays and build an array the doesn't have the numerical keys:
My current array:
Array
(
[0] => Array
(
[block_header14] => Array
(
[type] => block_header
[caption] => Silver
[collapsable] => 1
[collapsed] =>
)
[section14] => Array
(
[type] => checkbox_set
[name] => purchasable_memberships14
[caption] => Available Memberships
[values] => Array
(
[14] => Silver
[15] => Gold
)
[value] =>
)
)
[1] => Array
(
[block_header15] => Array
(
[type] => block_header
[caption] => Gold
[collapsable] => 1
[collapsed] =>
)
[section15] => Array
(
[type] => checkbox_set
[name] => purchasable_memberships15
[caption] => Available Memberships
[values] => Array
(
[14] => Silver
[15] => Gold
)
[value] =>
)
)
)
This what I want to end up with:
Array
(
[block_header14] => Array
(
[type] => block_header
[caption] => Silver
[collapsable] => 1
[collapsed] =>
)
[section14] => Array
(
[type] => checkbox_set
[name] => purchasable_memberships14
[caption] => Available Memberships
[values] => Array
(
[14] => Silver
[15] => Gold
)
[value] =>
)
[block_header15] => Array
(
[type] => block_header
[caption] => Gold
[collapsable] => 1
[collapsed] =>
)
[section15] => Array
(
[type] => checkbox_set
[name] => purchasable_memberships15
[caption] => Available Memberships
[values] => Array
(
[14] => Silver
[15] => Gold
)
[value] =>
)
)
Edit: I reworked the initial foreach and skipped the extra step: Sorry for the blurry question
foreach ($aMemLevels as $id =>$name) {
$aForm['inputs']['block_header'.$id] = array(
'type' => 'block_header',
'caption' => 'Available to ' . $name . ' Members',
'collapsable' => true,
'collapsed' => false
);
$aForm['inputs']['section'.$id] = array(
'type' => 'checkbox_set',
'name' => 'purchasable_memberships'.$id,
'values' => getMemberships(true),
'value' => $aValue,
);
}
$new_array = array();
foreach($array as $value) {
$new_array = array_merge($new_array, $value);
}
print_r($new_array);
I haven't tested it, but maybe something like this will help?
$new_array = array();
foreach ($multi_array as $inner_arr) {
$new_array = array_merge($new_array, $inner_array);
}
$multi_array being your initial, multidimensional array...
Let me know if that works.

Categories