Naming Keys in a Multidimensional Array in PHP - php

I have data from a csv file that I organized into a multidimensional array using the following method:
$handle = fopen("bankdata.csv", "r");
while(($data = fgetcsv($handle, 0 ,",")) !==FALSE) {
$transactions[] = $data;
}
The array now looks something like this:
Array
(
[0] => Array
(
[0] => 2000
[1] => paycheck
[2] => credit
)
[1] => Array
(
[0] => 75
[1] => grocery
[2] => debit
)
[2] => Array
(
[0] => 45
[1] => gas
[2] => debit
)
[3] => Array
(
[0] => 900
[1] => investments
[2] => credit
)
[4] => Array
(
[0] => 1500
[1] => bonus
[2] => credit
)
Now I would like to name the keys in each nested array. I thought I would create a new multidimensional array with an equal amount of nested arrays, their values being the intended name of the keys I would like to add to the original array, then do 'array_combine':
$names = array('amount','source','type');
$run = 1;
while($run < 6){
$run = $run +1;
$names2[] = $names;
}
$combine = array_combine($names2, $transactions);

You could use array combine:
$keynames=array('amount','source','type');
foreach ($transactions as $i=>$row) {
$transactions[$i]=>array_combine($keynames, $row);
}
The right way to solve the problem is not to read the the data into an array then transform it - transform it as you read it.
while(($data = fgetcsv($handle, 0 ,",")) !==FALSE) {
$transactions[]=array_combine($keynames, $data);
}
BTW PHP doesn't do multi-dimensional arrays - they're nested. Despite what it says in the manual, they only emulate multi-dimensional arrays.

Try the following:
$arr = array(
array(2000, 'paycheck', 'credit'),
array(75, 'grocery', 'debit'),
array(45, 'gas', 'debit'),
array(900, 'investments', 'credit'),
array(1500, 'bonus', 'credit')
);
$keys = array('amount','source','type');
// $a will make a reference to the array within $arr
// and override the array
foreach($arr as &$a)
{
// Override the array keys
$a = array_combine($keys, $a);
}
/* Output:
Array
(
[0] => Array
(
[amount] => 2000
[source] => paycheck
[type] => credit
)
[1] => Array
(
[amount] => 75
[source] => grocery
[type] => debit
)
[2] => Array
(
[amount] => 45
[source] => gas
[type] => debit
)
[3] => Array
(
[amount] => 900
[source] => investments
[type] => credit
)
[4] => Array
(
[amount] => 1500
[source] => bonus
[type] => credit
)
)
*/

Related

Sorting php array by column in ascending order

Array
(
[content_type] => Array
(
[0] => story
[1] => delhi
[2] => tez
)
[type] => Array
(
[0] => video_id
[1] => subcategory
[2] => story_id
)
[fetch_id] => Array
(
[0] => 32
[1] => 32
[2] => 2
)
[order] => Array
(
[0] => 6
[1] => 4
[2] => 5
)
[label] => Array
(
[0] => dsfs fdsf dsf sdf
[1] => dfsdfs
[2] => sdfsdfsd
)
[link] => Array
(
[0] => fsd fsdf sdf
[1] => fsdfsdfdsf
[2] => fsdfdsfds
)
[record] => Array
(
[0] => 10
[1] => 8
[2] => 12
)
)
Above is the array I have to sort this array in the basis of order field and it should shorted all the fields accordingly like below example.
$arr['order'][0] = 4;
$arr['order'][1] = 5;
$arr['order'][2] = 6;
$arr['type'][0] = 'subcategory';
$arr['type'][1] = 'story_id';
$arr['type'][2] = 'video_id';
and so on.....
You can try this -
$new = array();
// Extract and get the keys as values
$order = array_flip($array['order']);
// sort them according to keys
ksort($order);
// loop through main array
foreach($array as $key => $sub_array) {
// loop through order
foreach ($order as $o) {
// store the new value according to order
$new[$key][] = $sub_array[$o];
}
}
Demo
Some lesser solution:
asort($array['order']);
foreach ($array as $key => $subArray) {
$array[$key] = array_replace($array['order'], $subArray);
}
For reset a key sequence you may just to use array_values().

Finding specific key and return value in a multidimentional array

Consider the array below:
//$allmembers
Array
(
[0] => Array
(
[id] => 7
[name] => John Smith
)
[1] => Array
(
[id] => 8
[name] => John Skeet
)
[2] => Array
(
[id] => 9
[name] => Chuck Norris
)
[3] => Array
(
[id] => 10
[name] => Bruce Lee
)
)
I have another array like this:
//$schedules
Array
(
[0] => Array
(
[id] => 24
[title] => DAMN DAMN DAMN!
[description] =>
[room] => 5022
[start] => 1362783300
[end] => 1362783300
[participants] => 7,8
[members] => Array
(
)
)
[1] => Array
(
[id] => 22
[title] => blah blah
[description] =>
[room] => 5022
[start] => 1365024780
[end] => 1365026280
[participants] => 9,10
[members] => Array
(
)
)
)
So I have to read the participants keys in the second array, and then find the name from first array and add it to the member of the second array.
I am trying the code below but I aint got any success so far:
$allmembers = $_DB->Query("SELECT id,name FROM members");
for($i = 0; $i < count($schedules); $i++)
{
$schedules[$i]["members"] = array() ;
$mems = array();
$mems = explode(',', $schedules[$i]["participants"]);
for($j = 0; $j < count($mems); $j++)
{
//How to search the first array?
}
}
given that the two arrays exist above this block as $schedules and $allmembers, the following should work.
foreach($schedules as &$event)
{
$participants = array_flip(explode(',', $event['participants']));
$addThese = array();
foreach($allmembers as $member)
{
if (isset($participants[$member['id']]))
$addThese[] = $member;
}
$event['participants'] = $addThese;
} unset($event);
print_r($schedules);

Combine and sum values in multi-dimensional associative array using php

I have an associative array that looks like this:
Array (
[0] => Array (
[amount] => 3
[name] => Chuck
)
[1] => Array (
[amount] => 2
[name] => Steve
)
[2] => Array (
[amount] => 5
[name] =>
)
[3] => Array (
[amount] => 4
[name] => Chuck
)
[4] => Array (
[amount] =>
[name] => Chuck
)
)
I need to remove values that are missing a name or amount e.g. [2] and [4] and then sum the totals for each name so that the final array is:
Array (
[0] => Array (
[amount] => 7
[name] => Chuck
)
[1] => Array (
[amount] => 2
[name] => Steve
)
)
For anyone looking for this nowadays, this would be much cleaner:
$sum = array_sum(array_column($data, 'amount'));
Try this:
$starting_array = array( ... ); // Initial array with your setup
$final_array = array();
$sum = 0;
foreach ($starting_array as $idx => $data) {
if (!empty($data['amount']) && !empty($data['name'])) {
$final_array[$idx] = $data;
$sum += $data['amount'];
}
}
// After looping through all of the items, $final_array should contain all
// of the specific items that have an amount and name set. In addition, the
// total of all of the amounts will be in $sum.
Take a look at php's empty(). Note: If 0 is an allowed value, you may want to use is_null() instead.

list duplicates in PHP Array

i have a new problem and my mind is burning, i have an array in php
$test = array();
Array
(
[0] => Array
(
[account] => 14319896
[value] => 725.57
[id] => 280
)
[1] => Array
(
[account] => 163157
[value] => -723.57
[id] => 283
)
[2] => Array
(
[account] => 163157
[value] => 723.57
[id] => 284
)
[3] => Array
(
[account] => 161817
[value] => -723.57
[id] => 285
)
)
i need the accounts, they are more than one in this array, in this example i need $test[1][id] and $test[2][id]
have you an idea? i have no idea more at this time.
Thanks for your help.
Use the account number as key in a new array, count each entry and then take the items with a count > 1
$dupes = array();
foreach($array as $account) {
++$dupes[$account['account']];
}
$dupes = array_filter($dupes, function($count) { return $count > 1; });
Editing to answer the comments below the question …
If you want the IDs (or keys) of the duplicates, do not store the count directly, but use another array instead.
$dupes = array();
foreach($array as $key => $account) {
if(!array_key_exists($account, $dupes))
$dupes[$account['account']] = array();
$dupes[$account['account']][] = $account['id']; // or: = $key
}
$dupes = array_filter($dupes, function($ids) { return count($ids) > 1; });
You should change your architecture to have a associative array where keys are account number organized like that :
Array
(
[14319896] => Array
(
[0]=>Array(
[value] => 725.57
[id] => 280
)
)
[163157] => Array
(
[0]=>Array(
[value] => -723.57
[id] => 283
)
[1]=>Array(
[value] => 723.57
[id] => 284
)
)
[161817] => Array
(
[0]=>Array(
[value] => -723.57
[id] => 285
)
)
)
$dupes = array();
foreach($array as $key => $account) {
$dupes[$account['account']][] = array($account['id'],$account['value']);
}
Whith that architecture you can get everything you want thanks to array_filter :
$dups = array_filter($dupes, function($account){ return count($account)>1;});

How to group multidimensional array by sub-array value in and reassign keys in PHP

I looked at all the similar questions and samples (there are many) but still can't get this to work (though I think I am close).
I have an array of employee schedules pulled from a text file...
schedule.txt:
123,Joe,20120208,0845,1645
123,Joe,20120209,0800,1600
456,Sue,20120208,0900,1700
456,Sue,20120209,0700,1500
...
My code to generate the array is:
$schedule = file_get_contents('./schedule.txt');
$s = explode("\n", $schedule);
for ($i = 0; $i < count($s); $i++) {
$s[$i] = explode(",", $s[$i]);
}
print_r($s);
Output is:
Array
(
[0] => Array
(
[0] => 123
[1] => Joe
[2] => 20120208
[3] => 0845
[4] => 1645
)
[1] => Array
(
[0] => 123
[1] => Joe
[2] => 20120209
[3] => 0800
[4] => 1600
)
[2] => Array
(
[0] => 456
[1] => Sue
[2] => 20120208
[3] => 0900
[4] => 1700
)
[3] => Array
(
[0] => 456
[1] => Sue
[2] => 20120209
[3] => 0700
[4] => 1500
)
)
I am instead trying to group employees by Id in a new multidimensional array with output like this:
Array
(
[123] => Array
(
[0] => Array
(
[0] => Joe
[1] => 20120208
[2] => 0845
[3] => 1645
)
[1] => Array
(
[0] => Joe
[1] => 20120209
[2] => 0800
[3] => 1600
)
)
[456] => Array
(
[0] => Array
(
[0] => Sue
[1] => 20120208
[2] => 0900
[3] => 1700
)
[1] => Array
(
[0] => Sue
[1] => 20120209
[2] => 0700
[3] => 1500
)
)
)
I cannot for the life of me wrap my head around how to change my existing array into this new (different) output...
I am trying this but getting nowhere:
$newArr = array();
foreach($s as $k => $v) {
if(!isset($newArr[$v[0]])) {
$newArr[$v[0]] = array();
}
$newArr[$v[0]][] = array($v[0]);
}
Though my output is now:
Array
(
[123] => Array
(
[0] => Array
(
[0] => 123
)
[1] => Array
(
[0] => 123
)
)
[456] => Array
(
[0] => Array
(
[0] => 456
)
[1] => Array
(
[0] => 456
)
)
)
Any thoughts? I know I am missing something in my code around the line:
$newArr[$v[0]][] = array($v[0]);
I tried changing it to:
$newArr[$v[0]][] = array(0 => $v[1], 1 => $v[2], 2 => $v[3], 3 => $v[4]);
which gives my the right output, but I now get undefined offset errors. Plus, if the number of keys in the sub array changes, this code is now limited to the 4 I explicitly entered...
this should be enough, if I understood you right :)
$lines = file('./schedule.txt');
$employees = array();
foreach ($lines as $line)
{
$chunks = explode(',', $line);
$employees[$chunks[0]][] = array_slice($chunks, 1);
}
print_r($employees);
There is a function called fgetcsv to easily grab comma separated values. No need to do it yourself.
This code also solves your problem and properly handles blank lines:
if (($handle = fopen("schedules.csv", "r")) !== FALSE) {
$schedules = array();
while (($data = fgetcsv($handle)) !== FALSE) {
if ($data[0] !== null) { //blank lines return an array containing null
$schedules[$data[0]][] = array_slice($data, 1);
}
}
fclose($handle);
//do what you need to
} else {
// file failed to open
}
Note that I named the file .csv instead of .txt. I'd recommend that you save things that are comma separated values as .csv files. Maybe even define what each column is in the file as well.
<?php
//read the file into an array with each line being an entry
$schedule = file('./schedule.txt');
//empty array
$s = array();
//loop through file lines
foreach($schedule as $row){
//explode on comma
$row = explode(",", trim($row));
//if the id doesn't exist yet...
if(!isset($s[$row[0]])){
//...make it an empty array
$s[$row[0]] = array();
}
//add the row under the id
$s[$row[0]][] = $row;
}
print_r($s);
?>
You can use fscanf:
$handle = fopen('./schedule.txt', 'r');
$employees = array();
while ($line = fscanf($handle, '%d,%s')) {
$employees[$line[0]][] = explode(',', $line[1]);
}
fclose($handle);
print_r($employees);

Categories