shift array without indexOfOutBounds - php

I have 2 array's with the same length. array $gPositionStudents and array $gPositionInternships. Each student is assigned to a different internship, That part works.
Now I want the first element (index 0) of $gPositionStudent refer to the second (index 1) element of array $gPositionInternship. That implicitly means that the last element of $gPositionStudents refer to the first element of $gPositionInternship. (I included a picture of my explanation).
My Code is:
// Make table
$header = array();
$header[] = array('data' => 'UGentID');
$header[] = array('data' => 'Internships');
// this big array will contains all rows
// global variables.
global $gStartPositionStudents;
global $gStartPositionInternships;
//var_dump($gStartPositionInternships);
$rows = array();
$i = 0;
foreach($gStartPositionStudents as $value) {
foreach($gStartPositionInternships as $value2) {
// each loop will add a row here.
$row = array();
// build the row
$row[] = array('data' => $value[0]['value']);
//if($value[0] != 0 || $value[0] == 0) {
$row[] = array('data' => $gStartPositionInternships[$i]);
}
$i++;
// add the row to the "big row data (contains all rows)
$rows[] = array('data' => $row);
}
$output = theme('table', $header, $rows);
return $output;
Now I want that I can choose how many times, we can shift. 1 shift or 2 or more shifts. What I want exists in PHP?

Something like this:
//get the array keys for the interns and students...
$intern_keys = array_keys($gStartPositionInternships);
$student_keys = array_keys($gStartPositionStudents);
//drop the last intern key off the end and pin it to the front.
array_unshift($intern_keys, array_pop($intern_keys));
//create a mapping array to join the two arrays together.
$student_to_intern_mapping = array();
foreach($student_keys as $key=>$value) {
$student_to_intern_mapping[$value] = $intern_keys[$key];
}
You'll need to modify it to suit the rest of your code, but hopefully this will demonstrate a technique you could use. Note the key line here is the one which does array_unshift() with array_pop(). The comment in the code should explain what it's doing.

I think you want to do array_slice($gPositionsStudents, 0, X) where X is the number of moves to shift. This slices of a number of array elements. Then do array_merge($gPositionsStudents, $arrayOfSlicedOfPositions); to append these to the end of the original array.
Then you can do an array_combine to create one array with key=>value pairs from both arrays.

Related

CSV to Associative Array (One column as key and another as value)

I need to convert a CSV file into an associative array, using one column as key and another as value. For example, I have this:
Application,Warehouse,Item,UPC,MFUSA Item No.,"PRODUCT DESCR1","PRODUCT DESCR2",Warehouse ID,Qty
INVENTORY:,Muscle Foods USA,1st STEP B12 LIQUID 16oz,673131100064,8890004,1st STEP B12 LIQUID 16oz,CHERRY CHARGE,11,29
INVENTORY:,Muscle Foods USA,1st STEP B12 LIQUID 16oz,673131100316,8890007,1st STEP B12 LIQUID 16oz,TROPICAL BLAST,11,26
INVENTORY:,Muscle Foods USA,1st STEP B12 LIQUID 16oz,673131100064,8890004,1st STEP B12 LIQUID 16oz,CHERRY CHARGE,12,6
I have to use the column UPC as the key and Qty as the value, so that the array looks like..
array(
'673131100064' => '29',
'673131100316 => '26',
'673131100064' => '6',
);
I have tried several solutions found in Google as well as here, but none of them are close to what I need to achieve. This Question was something similar, but it was written in Python.
Sorry for my poor knowledge in PHP. Can you please guide me to the right direction?
With array_map you can parse the csv data and have an array to do as you wish.
Example:
// Parsing the data in csv file
$csv = array_map('str_getcsv', file('path/file.csv'));
/*At this point you already have an array with the data but
* the first row is the header row in your csv file */
//remove header row
array_shift($csv);
$data = [];
//Walk the array and add the needed data into some another array
array_walk($csv, function($row) use (&$data) {
$data[$row[3]] = $row[8];
});
And that's it.
However the data you show as an example has duplicate UPCs. You will overwrite some data if you want an array with the structure 'UPC' => 'Qty' . You can't have duplicate keys in an array.
If what you are looking for is to get the total Qty for each UPCs then you just need to add the already existing Qty with the new one if the UPC key already exists.
// Parsing the data in csv file
$csv = array_map('str_getcsv', file('file.csv'));
//remove header row
array_shift($csv);
$data = [];
//Walk the array and add the needed data into another array
array_walk($csv, function($row) use (&$data) {
$data[$row[3]] = ($data[$row[3]] ? $data[$row[3]] + (int) $row[8] : (int) $row[8]);
});
Or longer but clearer.
//Walk the array and add the needed data into another array
array_walk($csv, function($row) use (&$data) {
if(!empty($data[$row[3]]))
{
$data[$row[3]] += (int) $row[8];
}
else {
$data[$row[3]] = (int) $row[8];
}
});
Explanation in the comments of the code below
$array = [];
// Open file "$file" and checking that it is not empty
if (($handle = fopen($file, "r")) !== false) {
// loop on each csv line, stopping at end of file
while (($data = fgetcsv($handle)) !== false) {
// Excluding header row & checking data is not empty
if ($data[0] !== 'Application' && !empty($data[0])) {
// fgetcsv returns an array, on your example UPC is on key 3 and Qty on key 9
$array[] = [$data[3] => $data[9]];
}
}
fclose($handle);
}
return $array;
Here the keys are hard-coded but maybe you have a way to put it dynamically, it depends of your code & workflow. This is just a simple (I hope) demonstration.
I use the SplfileObject for reading. Then the first line is used as the key for all values. array_column with the column names can now be used for the desired result.
$csv = new SplFileObject('datei.csv');
$csv->setFlags(SplFileObject::READ_CSV
| SplFileObject::SKIP_EMPTY
| SplFileObject::READ_AHEAD
| SplFileObject::DROP_NEW_LINE
);
//Combine first row as key with values
$csvArr = [];
foreach($csv as $key => $row){
if($key === 0) $firstRow = $row;
else $csvArr[] = array_combine($firstRow,$row);
}
$arrQty = array_column($csvArr,'Qty','UPC');

How to find Smallest value of 2 different Variables in JSON and subtract other elements with that values

I need to find the smallest value of 2 variables in JSON object of particular key and subtract all keys with that value. Kindly lookinto following JSON Data
$print = '{"Table":[
{"Column":2,"Length":1,"Number":"A4","Row":12,"zindex":0},
{"Column":2,"Length":1,"Number":"A3","Row":11,"zindex":0},
{"Column":2,"Length":1,"Number":"A2","Row":9,"zindex":1},
{"Column":2,"Length":1,"Number":"A1","Row":8,"zindex":1},
{"Column":3,"Length":1,"Number":"B4","Row":12,"zindex":0},
{"Column":3,"Length":1,"Number":"B3","Row":11,"zindex":0},
{"Column":3,"Length":1,"Number":"B2","Row":9,"zindex":0},
{"Column":3,"Length":1,"Number":"B1","Row":8,"zindex":0},
{"Column":4,"Length":1,"Number":"C4","Row":12,"zindex":0},
{"Column":4,"Length":1,"Number":"C3","Row":11,"zindex":0},
{"Column":4,"Length":1,"Number":"C2","Row":9,"zindex":0},
{"Column":4,"Length":1,"Number":"C1","Row":8,"zindex":0}],"ResponseStatus":200,"Message":null}';
I want above JSON Data as given below.
$print = '{"Table":[
{"Column":2,"Length":1,"Number":"A4","Row":1,"zindex":0},
{"Column":2,"Length":1,"Number":"A3","Row":0,"zindex":0},
{"Column":2,"Length":1,"Number":"A2","Row":1,"zindex":1},
{"Column":2,"Length":1,"Number":"A1","Row":0,"zindex":1},
{"Column":3,"Length":1,"Number":"B4","Row":1,"zindex":0},
{"Column":3,"Length":1,"Number":"B3","Row":0,"zindex":0},
{"Column":3,"Length":1,"Number":"B2","Row":1,"zindex":1},
{"Column":3,"Length":1,"Number":"B1","Row":0,"zindex":1},
{"Column":4,"Length":1,"Number":"C4","Row":1,"zindex":0},
{"Column":4,"Length":1,"Number":"C3","Row":0,"zindex":0},
{"Column":4,"Length":1,"Number":"C2","Row":1,"zindex":1},
{"Column":4,"Length":1,"Number":"C1","Row":0,,"zindex":1}],"ResponseStatus":200,"Message":null}';
In the above JSON data kindly look into Row and zindex.
zindex has two values "0 and 1", here I want php code to find smallest value of zindex 0 separately and subtract remaining values of zindex 0 alone and same with zindex 1.
I have a PHP code that finds minimum value of row and subtract remaining rows with that value. But I dont know how to do it separately for different zindexs.
$rows = array();
$print = json_decode($print, true); // decode
foreach($print['Table'] as $val) { $rows[] = $val['Row']; }
$least = min($rows); // get least // $least = min(array_column($print['Table'], 'Row'));
foreach($print['Table'] as &$val) {
$val['Row'] -= $least; // make subtractions
}
$print = json_encode($print); // re encode
Kindly help me to solve this problem in PHP.
Try to replace the first foreach by:
foreach($print['Table'] as $val) {
if (!isset($rows[$val['zindex']])) {
$rows[$val['zindex']] = array();
}
$rows[$val['zindex']][] = $val['Row'];
}
Instead of having a 1-dimensional array with values, the array is 2-dimensional, having all Row values for each value of zindex.
Then, $least should be an array as well:
$least = array();
foreach ($rows as $zindex = $row) {
$least[$zindex] = min($row);
}
That will calculate the minimum value for each value of zindex separately.
Finally, the last foreach should discriminate for zindex as well:
foreach ($print['Table'] as &$val) {
$val['Row'] -= $least[$val['zindex']];
}
Success!

Can't push all array items into a second array PHP

So I have an array ($items) which has about 900 items in it. What I'm trying to do is, for the items that are read ($key["status"] == 1) which is about 300 items -> push those into a second array ($lifeSpanArray) with two attributes (added_date and read_date).
For some reason, when I try to push items into the lifespan array, I only have one item. Like I said, there are around 300 items that are status read - and I can dump those out, so I believe I am making a mistake with building my lifeSpanArray and pushing into it.
Any help much appreciated!
$items = $pocket->retrieve($params, $accessToken);
$numberArticles = count($items["list"]);
$hasRead = 0;
$hasNotRead = 0;
$readDatesArray = array();
$lifeSpanArray = array();
foreach ($items['list'] as $key) {
if ($key["status"] == 1) {
$hasRead++;
$timeAdded = date('m/d/Y', $key["time_added"]);
$dateRead = date('m/d/Y', $key["time_read"]);
// Where the problem is - only one item added
$lifeSpanArray['timeAdded'] = $timeAdded;
$lifeSpanArray['timeRead'] = $dateRead;
//Push into the read dates array
array_push($readDatesArray, $dateRead);
}
else {
$hasNotRead++;
}
}
var_dump($lifeSpanArray);
As you are overwriting your $lifeSpanArray array on each iteration you're must be getting only last entry so what you need is a two-dimension array,
Change this,
//Push into lifespan array
$lifeSpanArray['timeAdded'] = $timeAdded;
$lifeSpanArray['timeRead'] = $dateRead;
to,
$lifeSpanArray[] = array('timeAdded' => $timeAdded,'timeRead' => $dateRead);
$lifeSpanArray['timeAdded'] = $timeAdded;
$lifeSpanArray['timeRead'] = $dateRead;
For the above code, you are actually assigning a scalar value to $lifeSpanArray['timeAdded'] and $lifeSpanArray['timeRead'].
To treat them as array and push values to them, you should first initialize timeAdded and timeRead as arrays first:
$lifeSpanArray = array(
'timeAdded' => array(),
'timeRead' => array()
);
And pushing values to them within the foreach loop:
$lifeSpanArray['timeAdded'][] = $timeAdded;
$lifeSpanArray['timeRead'][] = $dateRead;

Flatten RecursiveIteratorIterator array by children

I can't seem to figure out the best way to do this. I have a RecursiveIteratorIterator.
$info = new RecursiveIteratorIterator(
new GroupIterator($X), # This is a class that implements RecursiveIterator
RecursiveIteratorIterator::SELF_FIRST
);
Note: GroupIterator is a class that handles our custom formatted data
When I loop through it, I get exactly what I expect.
foreach($info as $data){
echo $info->getDepth().'-'.$data."\n";
}
The output is:
0-a
1-b
2-c
2-d
1-e
2-f
0-g
1-h
2-i
This is correct, so far. Now, what I want is to flatten the parents and children into a single array. I want one row for each max-depth child. The output I am trying to get is:
0-a 1-b 2-c
0-a 1-b 2-d
0-a 1-e 2-f
0-g 1-h 2-i
I can't figure out how to do this. Each iteration over the loop gives me another row, how can I combine the rows together that I want?
I managed to figure it out. #ComFreek pointed me in the right direction. Instead of using a counter, I used the current depth to check when I hit the lowest child, then I added the data to the final array, otherwise I added it to a temp array.
$finalArray = array();
$maxDepth = 2;
foreach($info as $data){
$currentDepth = $info->getDepth();
// Reset values for next parent
if($currentDepth === 0){
$currentRow = array();
}
// Add values for this depth
$currentRow[$currentDepth] = $data;
// When at lowest child, add to final array
if($currentDepth === $maxDepth){
$finalArray[] = $currentRow;
}
}
Try adding a counter variable:
// rowNr loops through 0, 1, 2
$rowNr = 0;
$curData = [];
$outputData = [];
foreach($info as $data){
// got last element, add the temp data to the actual array
// and reset temp array and counter
if ($rowNr == 2) {
$outputData[] = $curData;
$curData = [];
$rowNr == 0;
}
else {
// save temp data
$curData[] = $info->getDepth() . '-' . $data;
}
$rowNr++;
}

compare elements of array and based on comparison retrieve array data

I have two arrays, there is one element which is 'name' common in first and second array. Now, I want to retrieved values from second array if first array value match to second one.
code for first array:
$rs = array();
foreach ( $ex_array as $data ) {
$rs[] = array( 'name' => $data['name'] );
}
Second Array:
$entries_data = array();
foreach ( $array as $entry ) {
$name = $entry['name']['value'];
$email = $entry['email']['value'];
$entries_data[] = array(
'name' => $name,
'email' => $email
);
}
Problem is, there is only multiple names in first array, and then i have to compare first array names with the second one array, if there is match then whole data is retrieved from second array for specific name. I am trying to do this by using in_array function for search names in second array but can't fetch whole values. Any suggestions or help would be grateful for me.
is_array() is used for 1d arrays which isnt ur case use this function taken from the php documentation comments and edited by me to work for ur example
function in_multiarray($elem, $array)
{
$top = sizeof($array) - 1;
$bottom = 0;
while($bottom <= $top)
{
if($array[$bottom]['name'] == $elem)
return true;
else
if(is_array($array[$bottom]['name']))
if(in_multiarray($elem, ($array[$bottom]['name'])))
return true;
$bottom++;
}
return false;
}

Categories