PHP For Each Append Array - php

Example code array: https://eval.in/639002
A guest with (user_id = 1) bought multiple tickets (ticket_id = 1 & 2) On event (event_id = 11).
I am expecting the result format:
[ticket] => Array
(
[1] => Ticket Name, ***
[2] => Ticket Name
)
Code example below:
$data_db = array(
array(
'id' => 1,
'user_id' => 1,
'event_id' => 11,
'ticket_id' => 1,
'user_name' => 'guest 1'
),
array(
'id' => 2,
'user_id' => 2,
'event_id' => 11,
'ticket_id' => 1,
'user_name' => 'guest 2'
),
array(
'id' => 3,
'user_id' => 3,
'event_id' => 22,
'ticket_id' => 1,
'user_name' => 'guest 3'
),
array(
'id' => 4,
'user_id' => 1,
'event_id' => 11,
'ticket_id' => 2,
'user_name' => 'guest 1'
)
);
$output = [];
foreach ( $data_db as $key => $row ) {
$output[ $row['event_id'] ]['event'] = 'Event Name';
$output[ $row['event_id'] ]['attendee'][ $row['user_id'] ] = $row;
$output[ $row['event_id'] ]['attendee'][ $row['user_id'] ]['ticket'][ $row['ticket_id'] ] = 'Ticket Name';
}
print_r($output);
Current result
Array
(
[11] => Array
(
[event] => Event Name
[attendee] => Array
(
[1] => Array
(
[id] => 4
[user_id] => 1
[event_id] => 11
[ticket_id] => 2
[user_name] => guest 1
[ticket] => Array
(
[2] => Ticket Name
)
)
[2] => Array
(
[id] => 2
[user_id] => 2
[event_id] => 11
[ticket_id] => 1
[user_name] => guest 2
[ticket] => Array
(
[1] => Ticket Name ***
)
)
)
)
[22] => Array
(
[event] => Event Name
[attendee] => Array
(
[3] => Array
(
[id] => 3
[user_id] => 3
[event_id] => 22
[ticket_id] => 1
[user_name] => guest 3
[ticket] => Array
(
[1] => Ticket Name
)
)
)
)
)

First of you could start by sorting out an array of tickets of which ticket belongs to which user:
$output = [];
foreach($data_db as $key=>$row) {
// Define new $tickets Array E.g ['guest_name']=>['ticket_id']
$tickets[$row['user_name']][] = $row['ticket_id'];
$output [] = [
'id'=>$row['id'],
'user_id'=>$row['user_id'],
'event_id'=>$row['event_id'],
'user_name'=>$row['user_name'],
'tickets'=>[]
];
}
Your output of $tickets would look like:
Array
(
[guest 1] => Array
(
[0] => 1
[1] => 2
)
[guest 2] => Array
(
[0] => 1
)
[guest 3] => Array
(
[0] => 1
)
)
Then you can combine them, like this:
foreach($output as $k=>$v){
foreach($tickets as $guest=>$ticket){
if($v['user_name'] == $guest){
$output[$k]['tickets'] = $ticket;
}
}
}
Your output is:
Array
(
[0] => Array
(
[id] => 1
[user_id] => 1
[event_id] => 11
[user_name] => guest 1
[tickets] => Array
(
[0] => 1
[1] => 2
)
)
[1] => Array
(
[id] => 2
[user_id] => 2
[event_id] => 11
[user_name] => guest 2
[tickets] => Array
(
[0] => 1
)
........

Related

merge two array with loop and key name

i have two separate arrays $first_one:
Array
(
[0] => Array
(
[_date] => 2019-10-16
[_number] => 1
[_order] => 1
[name] => jack
[other_ids] => Array
(
[b_id] => 1253
)
)
[1] => Array
(
[_date] => 2020-10-11
[_number] => 2
[_order] => 2
[name] => joey
[other_ids] => Array
(
[b_id] => 1433
)
)
)
and the $second_array:
Array
(
[0] => Array
(
[date] => 2019-10-16
[number] => 1
[order] => 1
[name] => jack
[last_name] => foobar
[other_ids] => Array
(
[b_id] => 1253
)
)
[1] => Array
(
[date] => 2020-10-11
[number] => 2
[order] => 2
[name] => joey
[last_name] => foobar
[other_ids] => Array
(
[b_id] => 1433
)
)
[2] => Array
(
[date] => 2020-10-28
[number] => 3
[order] => 3
[name] => tom
[last_name] => foobar
[other_ids] => Array
(
[b_id] => 1593
)
)
)
they are very similar but they came from different api's and they are different in numbers and also some key names.
so what i'm trying to do is to count the $first_one arrays and if for that many loop through the $second_one (in this example is 2) and if the [_number] [_order] from $first_one was equal (==) to [number] [number] $second_one then take some info (for example the last name) from it and put in a new array.
so is this possible to do?
$arr1 = [ [ '_date' => '2019-10-16','_number' => 1,'_order' => 1,
'name' => 'jack','other_ids' => ['b_id' => 1253]
],
['_date' => 2020-10-11,'_number' => 2,'_order' => 2,
'name' => 'joey','other_ids' => ['b_id' => 1433]
]
];
$arr2 = [ [ 'date' => '2019-10-16','number' => '1','order' => '1',
'name' => 'jack','last_name' => 'foobar','other_ids' => ['b_id' => 1253]
],
[ 'date' => '2019-10-11','number' => '2','order' => '2',
'name' => 'joey','last_name' => 'foobar','other_ids' => ['b_id' => 1433]
],
[ 'date' => '2019-10-28', 'number' => '3', 'order' => '3',
'name' => 'tom', 'last_name' => 'foobar', 'other_ids' => ['b_id' => 1593]
],
];
// first make second array more directly searchable
// make new array with the `number` as the key
foreach( $arr2 as $a){
$arr2new[$a['number']] = $a;
}
foreach ($arr1 as $a) {
if ( array_key_exists($a['_number'], $arr2new) &&
$a['_order'] == $arr2new[$a['_order']]['order'] )
{
$merged[] = ['name'=>$a['name'], 'other_ids' => $a['other_ids']];
}
}
print_r($merged);
RESULT
Array
(
[0] => Array (
[name] => jack
[other_ids] => Array
(
[b_id] => 1253
)
)
[1] => Array (
[name] => joey
[other_ids] => Array
(
[b_id] => 1433
)
)
)

how to get a slice of a multidimensional array using an array with index keys

I have an array
$arr = [
[
'id' => 10,
'name' => 'John',
'occupation' => 'engineer',
'points' => 10
],
[
'id' => 10,
'name' => 'John',
'occupation' => 'librarian',
'points' => 14
],
[
'id' => 7,
'name' => 'Sarah',
'occupation' => 'artist',
'points' => 21
],
[
'id' => 7,
'name' => 'Sarah',
'occupation' => 'teacher',
'points' => 17
],
[
'id' => 10,
'name' => 'John',
'occupation' => 'butcher',
'points' => 7
],
[
'id' => 7,
'name' => 'Sarah',
'occupation' => 'engineer',
'points' => 9
],
[
'id' => 25,
'name' => 'Andreea',
'occupation' => 'judge',
'points' => 11
]
];
And I use this built in functions to get unique ids:
$people = array_column($arr, 'id', 'id');
And then I use a foreach to get every occurrence of each user in the main array $arr:
foreach($people as $id){
$keys = array_keys(array_column($arr, 'id'), $id);
}
This is the return:
Array
(
[0] => 0
[1] => 1
[2] => 4
)
Array
(
[0] => 2
[1] => 3
[2] => 5
)
Array
(
[0] => 6
)
Now in order to build a small array for each person I could loop trough this small arrays that contain the keys from the main array and get the values and ending up with small slices.
But, how can I get the actual $arr values for each person instead of getting just the keys? (using as little resources as possible)
I need the result to be like this:
Array
(
[10] => Array
(
[0] => Array
(
[id] => 10
[name] => John
[occupation] => engineer
[points] => 10
)
[1] => Array
(
[id] => 10
[name] => John
[occupation] => librarian
[points] => 14
)
[2] => Array
(
[id] => 10
[name] => John
[occupation] => butcher
[points] => 7
)
)
[7] => Array
(
[0] => Array
(
[id] => 7
[name] => Sarah
[occupation] => artist
[points] => 21
)
[1] => Array
(
[id] => 7
[name] => Sarah
[occupation] => teacher
[points] => 17
)
[2] => Array
(
[id] => 7
[name] => Sarah
[occupation] => engineer
[points] => 9
)
)
[25] => Array
(
[0] => Array
(
[id] => 25
[name] => Andreea
[occupation] => judge
[points] => 11
)
)
)
P.S: I don't need to keep the key index the same.
You can do it in a more efficient way,Demo
$result = [];
foreach($arr as $v){
$result[$v["id"]][] = $v;
}
print_r($result);
use a function of group by like:
$byGroup = group_by("id", $arr);
function group_by($key, $data) {
$result = array();
foreach($array as $val) {
if(array_key_exists($key, $val)){
$result[$val[$key]][] = $val;
}else{
$result[""][] = $val;
}
}
return $result;
}

Remove parent array including the children if the children value found empty

I have this array structure.
I'm trying to remove those whole array if I found the [empevalpptwo] empty or null, so if the [empevalpptwo] is empty the whole [4] => Array should be remove.
Right now i'm just trying to get the parent index so I can just remove it by index
Is there any good solution like filtering recursively?
$kra = array_column($ppform_plan->toArray(), 'kra');
$emp_eval_pptwo = array_search('', array_column($kra, 'empevalpptwo'));
//should return 4
Array
(
[4] => Array
(
[id] => 50
[user_id] => 6282
[specific_user_id] => 6281
[eval_cat_id] => 2
[format_cat] => 1
[title] => This istesting
[desc] =>
[weight] => 50
[bsc_weight_group] =>
[bsc_rating] =>
[sequence] =>
[created_at] => 2019-05-22 10:55:23
[updated_at] => 2019-05-22 10:55:23
[kra] => Array
(
[0] => Array
(
[id] => 77
[user_id] => 6282
[bsc_id] => 50
[index] => 0
[kra_title] => ttes lang muna
[kra_desc] =>
[kra_weight] => 25
[sat] => 521
[at] => 4
[ot] => 535
[rating_per_kra] =>
[rating_per_kra_cat] =>
[net_weighting] => 5
[rank] => 1
[remarks] =>
[indicator_text] =>
[created_at] =>
[updated_at] =>
[empevalpptwo] =>
)
[1] => Array
(
[id] => 78
[user_id] => 6282
[bsc_id] => 50
[index] => 1
[kra_title] => talga e2 pa o
[kra_desc] =>
[kra_weight] => 25
[sat] => 5
[at] => 2
[ot] => 4
[rating_per_kra] =>
[rating_per_kra_cat] =>
[net_weighting] => 4
[rank] => 2
[remarks] =>
[indicator_text] =>
[created_at] =>
[updated_at] =>
[empevalpptwo] =>
)
)
)
)
Something akin to:
<?php
$items =
[
1 =>
[
'foo'=>
[
[
'bar' => '',
],
[
'bar' => '',
]
]
],
2 =>
[
'foo'=>
[
[
'bar' => 'baz'
]
]
]
];
foreach ($items as $k => $item)
if(empty(array_filter(array_column($item['foo'], 'bar'))))
unset($items[$k]);
var_export($items);
Output:
array (
2 =>
array (
'foo' =>
array (
0 =>
array (
'bar' => 'baz',
),
),
),
)
You should try this :
$data = array_map('array_filter', $data);
$data = array_filter($data);
UPDATED
and for checking inner values you can use this :
$array = array_filter($array, function($v) { return !empty($v['empevalpptwo']); });
Orginal
Array
(
[con] => Array
(
[address] => Array
(
[city] => ahmedabad
)
[personalinfo] =>
)
)
Result :
Array
(
[con] => Array
(
[address] => Array
(
[city] => ahmedabad
)
)
)

Organizing multi-dimensional array of inventory

I need help organizing my inventory array. The structure is one big inventory array, with array of items inside. Per item array consists of the following:
item, item_group, item_no and array sold. sold consists of inner arrays with dates and quantity. Now, I'm having trouble organizing it for my needed output. I'll give you guys sample of input and output. So please do check and it's very much appreciated.
Sample part of my $inventory array
Array
(
[0] => Array
(
[item] => NK
[item_group] => 5
[sold] => Array
(
[0] => Array
(
[quantity] => 11
[date] => 2017-10-28
)
[1] => Array
(
[quantity] => 1
[date] => 2017-10-29
)
)
[item_no] => 1
)
[1] => Array
(
[item] => FL
[item_group] => 5
[sold] => Array
(
[0] => Array
(
[quantity] => 7
[date] => 2017-10-28
)
[1] => Array
(
[quantity] => 2
[date] => 2017-10-29
)
)
[item_no] => 2
)
[2] => Array
(
[item] => AD
[item_group] => 5
[sold] => Array
(
[0] => Array
(
[quantity] => 5
[date] => 2017-10-28
)
[1] => Array
(
[quantity] => 3
[date] => 2017-10-29
)
)
[item_no] => 3
)
[3] => Array
(
[item] => CV
[item_group] => 5
[sold] => Array
(
[0] => Array
(
[quantity] => 4
[date] => 2017-10-28
)
[1] => Array
(
[quantity] => 6
[date] => 2017-10-29
)
)
[item_no] => 4
)
[4] => Array
(
[item] => NB
[item_group] => 5
[sold] => Array
(
[0] => Array
(
[quantity] => 12
[date] => 2017-10-28
)
[1] => Array
(
[quantity] => 4
[date] => 2017-10-29
)
)
[item_no] => 5
)
[5] => Array
(
[item] => SP
[item_group] => 5
[sold] => Array
(
[0] => Array
(
[quantity] => 4
[date] => 2017-10-28
)
[1] => Array
(
[quantity] => 6
[date] => 2017-10-29
)
)
[item_no] => 6
)
[6] => Array
(
[item] => WB
[item_group] => 5
[sold] => Array
(
[0] => Array
(
[quantity] => 5
[date] => 2017-10-28
)
[1] => Array
(
[quantity] => 2
[date] => 2017-10-29
)
)
[item_no] => 7
)
[7] => Array
(
[item] => wny
[item_group] => 12
[sold] => Array
(
[0] => Array
(
[quantity] => 4
[date] => 2017-10-28
)
[1] => Array
(
[quantity] => 6
[date] => 2017-10-29
)
)
[item_no] => 8
)
[8] => Array
(
[item] => bs
[item_group] => 12
[sold] => Array
(
[0] => Array
(
[quantity] => 15
[date] => 2017-10-28
)
[1] => Array
(
[quantity] => 2
[date] => 2017-10-29
)
)
[item_no] => 9
)
[9] => Array
(
[item] => st
[item_group] => 12
[sold] => Array
(
[0] => Array
(
[quantity] => 16
[date] => 2017-10-29
)
)
[item_no] => 10
)
[10] => Array
(
[item] => ayhtdws
[item_group] => 12
[sold] => Array
(
[0] => Array
(
[quantity] => 2
[date] => 2017-10-29
)
)
[item_no] => 11
)
[11] => Array
(
[item] => sif
[item_group] => 12
[sold] => Array
(
[0] => Array
(
[quantity] => 3
[date] => 2017-10-29
)
)
[item_no] => 12
)
[12] => Array
(
[item] => bb
[item_group] => 12
[sold] => Array
(
[0] => Array
(
[quantity] => 6
[date] => 2017-10-29
)
)
[item_no] => 13
)
)
From there, what I want to display is like this. Grouped by date ascending. And each item => quantity sold
Array
(
[0] => Array
(
[date] => 2017-10-28
[NK] => 11
[FL] => 7
[AD] => 5
[CV] => 4
[NB] => 12
[SP] => 4
[WB] => 5
[wny] => 4
[bs] => 15
)
[1] => Array
(
[date] => 2017-10-29
[NK] => 1
[FL] => 2
[AD] => 3
[CV] => 6
[NB] => 4
[SP] => 6
[WB] => 2
[wny] => 6
[bs] => 2
[st] => 16
[ayhtdws] => 2
[sif] => 3
[bb] => 6
)
)
I've spent almost 3 days figuring this out and up to this writing, I was only able to make it this far
$result = array();
$dates = array();
foreach ($inventory as $key => $item) {
foreach ($item['sold'] as $k => $v) {
array_push($dates, $v['date']);
}
}
$dates = array_unique($dates);
foreach($dates as $key => $value) {
array_push($result, array('date' => $value));
}
foreach ($dates as $rkey => $rvalue) {
foreach ($inventory as $key => $item) {
foreach ($item['sold'] as $k => $v) {
if ($v['date'] = $result[$key]['date']) {
array_push($result[$key][$item['item']] = $v['quantity']);
}
}
}
}
return $result;
Which of course gives me this sad result
Array
(
[0] => Array
(
[date] => 2017-10-28
[NK] => 1
)
[1] => Array
(
[date] => 2017-10-29
[FL] => 2
)
)
And to make things worse, we have this rule about cyclomatic complexities that we should only have at most 3 loop/conditions and up to 3 nesting levels per loop/conditions. And the whole organizing should not have any user created functions.
Even if not following the rules, I wasn't able to figure it out for days. Sorry if problem is long. Please help :(
Update: var_export($inventory) output
array (
0 =>
array (
'item' => 'NK',
'item_group' => '5',
'sold' =>
array (
0 =>
array (
'quantity' => '11',
'date' => '2017-10-28',
),
1 =>
array (
'quantity' => '1',
'date' => '2017-10-29',
),
),
'item_no' => '1',
),
1 =>
array (
'item' => 'FL',
'item_group' => '5',
'sold' =>
array (
0 =>
array (
'quantity' => '7',
'date' => '2017-10-28',
),
1 =>
array (
'quantity' => '2',
'date' => '2017-10-29',
),
),
'item_no' => '2',
),
2 =>
array (
'item' => 'AD',
'item_group' => '5',
'sold' =>
array (
0 =>
array (
'quantity' => '5',
'date' => '2017-10-28',
),
1 =>
array (
'quantity' => '3',
'date' => '2017-10-29',
),
),
'item_no' => '3',
),
3 =>
array (
'item' => 'CV',
'item_group' => '5',
'sold' =>
array (
0 =>
array (
'quantity' => '4',
'date' => '2017-10-28',
),
1 =>
array (
'quantity' => '6',
'date' => '2017-10-29',
),
),
'item_no' => '4',
),
4 =>
array (
'item' => 'NB',
'item_group' => '5',
'sold' =>
array (
0 =>
array (
'quantity' => '12',
'date' => '2017-10-28',
),
1 =>
array (
'quantity' => '4',
'date' => '2017-10-29',
),
),
'item_no' => '5',
),
5 =>
array (
'item' => 'SP',
'item_group' => '5',
'sold' =>
array (
0 =>
array (
'quantity' => '4',
'date' => '2017-10-28',
),
1 =>
array (
'quantity' => '6',
'date' => '2017-10-29',
),
),
'item_no' => '6',
),
6 =>
array (
'item' => 'WB',
'item_group' => '5',
'sold' =>
array (
0 =>
array (
'quantity' => '5',
'date' => '2017-10-28',
),
1 =>
array (
'quantity' => '2',
'date' => '2017-10-29',
),
),
'item_no' => '7',
),
7 =>
array (
'item' => 'wny',
'item_group' => '12',
'sold' =>
array (
0 =>
array (
'quantity' => '4',
'date' => '2017-10-28',
),
1 =>
array (
'quantity' => '6',
'date' => '2017-10-29',
),
),
'item_no' => '8',
),
8 =>
array (
'item' => 'bs',
'item_group' => '12',
'sold' =>
array (
0 =>
array (
'quantity' => '15',
'date' => '2017-10-28',
),
1 =>
array (
'quantity' => '2',
'date' => '2017-10-29',
),
),
'item_no' => '9',
),
9 =>
array (
'item' => 'st',
'item_group' => '12',
'sold' =>
array (
0 =>
array (
'quantity' => '16',
'date' => '2017-10-29',
),
),
'item_no' => '10',
),
10 =>
array (
'item' => 'ayhtdws',
'item_group' => '12',
'sold' =>
array (
0 =>
array (
'quantity' => '2',
'date' => '2017-10-29',
),
),
'item_no' => '11',
),
11 =>
array (
'item' => 'sif',
'item_group' => '12',
'sold' =>
array (
0 =>
array (
'quantity' => '3',
'date' => '2017-10-29',
),
),
'item_no' => '12',
),
12 =>
array (
'item' => 'bb',
'item_group' => '12',
'sold' =>
array (
0 =>
array (
'quantity' => '6',
'date' => '2017-10-29',
),
),
'item_no' => '13',
),
)
I don't know if this is more or less the same as Erwin's code, but I wrote this code 13 hours ago and had to wait for the array.
Edit; I have tested Erwin's code and it seems we have close to matching code.
He makes one loop more to get the date in there but it's more or less the same.
I loop the array and the subarray sold.
I make the new array key the date example:
Echo $new['2017-10-28']['nk']; // 11
And if the date key is not set already I create it.
Once the loop is done I use array_values to remove the date keys making the array look like:
Echo $new[0]['nk']; // 11
The code:
$new =[];
Foreach($inventory as $sub){
Foreach($sub["sold"] as $sold){
If (!isset($new[$sold["date"]]["date"])) $new[$sold["date"]]["date"] = $sold["date"];
$new[$sold["date"]][$sub["item"]] = $sold["quantity"];
}
}
$new = array_values($new);
Var_dump($new);
https://3v4l.org/mGJSX
I've run through some tests and workarounds and come up with this solution. I've managed to do it by using ksort(), array_values()and array_key_exists(). I used the date first as an array key to contain all items sold on that date. Then, move it inside the array after gathering all items, then renumbered the array. Further explanation is given through code comments
// result array
$result = array();
// Loop for each item on inventory
foreach ($inventory as $inv) {
// Loop for each sold array
foreach ($inv['sold'] as $item) {
// date sold
$date = $item['date'];
// Check if date already exist in result array as key
// If not, Create new array with key equal to date and push to result array
if (!array_key_exists($date, $result)) {
$result[$date] = array();
}
// Add array of item => quantity to corresponding date array inside result array
$result[$date][$inv['item']] = $item['quantity'];
}
}
// From here you already have each item => quantity sold inside each date array
// e.g. $result = array( '2017-10-28' => array('NK' => '11', 'FL' => '7', ...) );
// Sort keys which are dates ascending
ksort($result);
// Loop to results and set
foreach ($result as $key => $value) {
$result[$key]['date'] = $key;
}
// Renumber Keys
$result = array_values($result);
// Print result
echo '<pre>';
print_r($result);
Output
Array
(
[0] => Array
(
[NK] => 11
[FL] => 7
[AD] => 5
[CV] => 4
[NB] => 12
[SP] => 4
[WB] => 5
[wny] => 4
[bs] => 15
[date] => 2017-10-28
)
[1] => Array
(
[NK] => 1
[FL] => 2
[AD] => 3
[CV] => 6
[NB] => 4
[SP] => 6
[WB] => 2
[wny] => 6
[bs] => 2
[st] => 16
[ayhtdws] => 2
[sif] => 3
[bb] => 6
[date] => 2017-10-29
)
)

How to construct sub arrays from a main array

I would like to construct sub n number of arrays from a multi dimensional array depends on the data. For example: I have a main array as
Array
(
[0] => Array
(
[id] => 1
[status] => -1
)
[1] => Array
(
[id] => 2
[status] => 1
)
[2] => Array
(
[id] => 3
[status] => 2
)
[3] => Array
(
[id] => 4
[status] => 2
)
[4] => Array
(
[id] => 5
[status] => 2
)
)
I would like to get 3 arrays from this array depends on the no and type of status value
like
array{
[0]=array(
[status]=-1
[count]=1
)
[1]=array(
[status]=1
[count]=1
)
[2]=array(
[status]=2
[count]=3
)
}
Thanks in advance,
Sunil Kumar P
You mean like this?:
$array = array(
array('id' => 1, 'status' => -1),
array('id' => 2, 'status' => 1),
array('id' => 3, 'status' => 2),
array('id' => 4, 'status' => 2),
array('id' => 5, 'status' => 2)
);
$statuses = array();
foreach($array as $one){
if(!isset($statuses[$one['status']])){ $statuses[$one['status']] = 0; }
$statuses[$one['status']]++;
}
$newArray = array();
foreach($statuses as $key => $val){
$newArray[] = array('status' => $key, 'count' => $val);
}
print_r($newArray);
/*Array
(
[0] => Array
(
[status] => -1
[count] => 1
)
[1] => Array
(
[status] => 1
[count] => 1
)
[2] => Array
(
[status] => 2
[count] => 3
)
)*/

Categories