How to split multidimensional array into arrays based on the values - PHP - php

I have this array, it could look something like this:
array(756) {
[0]=>
array(2) {
[0]=>
string(12) "joint_temps5"
[1]=>
string(4) "23.5"
}
[1]=>
array(2) {
[0]=>
string(12) "joint_temps4"
[1]=>
string(4) "23.5"
}
[2]=>
array(2) {
[0]=>
string(12) "joint_temps3"
[1]=>
string(2) "24"
}
[3]=>
array(2) {
[0]=>
string(12) "joint_temps2"
[1]=>
string(4) "24.5"
}
[4]=>
array(2) {
[0]=>
string(12) "joint_temps1"
[1]=>
string(2) "25"
}
[5]=>
array(2) {
[0]=>
string(12) "joint_temps0"
[1]=>
string(4) "25.5"
}
[6]=>
array(2) {
[0]=>
string(12) "joint_temps5"
[1]=>
string(4) "23.5"
}
[7]=>
array(2) {
[0]=>
string(12) "joint_temps4"
[1]=>
string(4) "23.5"
}
[8]=>
array(2) {
[0]=>
string(12) "joint_temps3"
[1]=>
string(2) "24"
}
[9]=>
array(2) {
[0]=>
string(12) "joint_temps2"
[1]=>
string(4) "24.5"
}
[10]=>
array(2) {
[0]=>
string(12) "joint_temps1"
[1]=>
string(2) "25"
}
[11]=>
array(2) {
[0]=>
string(12) "joint_temps0"
[1]=>
string(4) "25.5"
}
etc...};
How would i go about looping thru and splitting it up into arrays based on the value in the inner arrays[0] ex: "joint_temps5".
I have tested quite a few things but without success. My problem mainly is i dont know what might be in the string in the arrays.
I would like to end up with arrays like:
$array1[] = array(x_amount){
[0]=>
array(2) {
[0]=>
string(12) "joint_temps5"
[1]=>
string(4) "23.5"
}
[1]=>
array(2) {
[0]=>
string(12) "joint_temps5"
[1]=>
string(4) "23.5"
}
}
$array2[] = array(x_amount){
[0]=>
array(2) {
[0]=>
string(12) "joint_temps4"
[1]=>
string(4) "23.5"
}
[1]=>
array(2) {
[0]=>
string(12) "joint_temps4"
[1]=>
string(4) "23.5"
}
}
}
etc.

I would recommend to create a new array from your input array, using the value as an index of the array to be created, like so:
// test-set: input array is $a
$a[0] = array("joint_temps5","23.5");
$a[1] = array("joint_temps3","24");
$a[2] = array("joint_temps2","24.5");
$a[3] = array("joint_temps1","25");
$a[4] = array("joint_temps0","25.5");
$a[5] = array("joint_temps5","23.5");
$a[6] = array("joint_temps4","23.5");
$a[7] = array("joint_temps3","24");
$a[8] = array("joint_temps2","24.5");
$a[9] = array("joint_temps1","25");
foreach($a as $key => $value){
$b[$value[0]][] = $value; // *Explained below
}
*"Explained below": $a is the source array, $b is the newly created array.
$b[$value[0]][] means it wil create a new element for array $b[$value[0]]. And $value[0] will be substituted by the first value in the element of $a that the foreach loop hits.
Example: the first element of $a is this array: array("joint_temps5","23.5"). So in the foreach loop, the text "joint_temps5" ($value[0] in the foreach) will be used as a key/index to create a new element for array $b. The [] means that with every new execution of this line, a new element, with that key value $value[0], will be added.
It will result in:
array(6) {
["joint_temps5"]=>
array(2) {
[0]=>
array(2) {
[0]=>
string(12) "joint_temps5"
[1]=>
string(4) "23.5"
}
[1]=>
array(2) {
[0]=>
string(12) "joint_temps5"
[1]=>
string(4) "23.5"
}
}
["joint_temps3"]=>
array(2) {
[0]=>
array(2) {
[0]=>
string(12) "joint_temps3"
[1]=>
string(2) "24"
}
[1]=>
array(2) {
[0]=>
string(12) "joint_temps3"
[1]=>
string(2) "24"
}
}
["joint_temps2"]=>
array(2) {
[0]=>
array(2) {
[0]=>
string(12) "joint_temps2"
[1]=>
string(4) "24.5"
}
[1]=>
array(2) {
[0]=>
string(12) "joint_temps2"
[1]=>
string(4) "24.5"
}
}
["joint_temps1"]=>
array(2) {
[0]=>
array(2) {
[0]=>
string(12) "joint_temps1"
[1]=>
string(2) "25"
}
[1]=>
array(2) {
[0]=>
string(12) "joint_temps1"
[1]=>
string(2) "25"
}
}
["joint_temps0"]=>
array(1) {
[0]=>
array(2) {
[0]=>
string(12) "joint_temps0"
[1]=>
string(4) "25.5"
}
}
["joint_temps4"]=>
array(1) {
[0]=>
array(2) {
[0]=>
string(12) "joint_temps4"
[1]=>
string(4) "23.5"
}
}
}

You could loop through your array, and populate a new array using the string as a key, so something like:
foreach ($array as $working_array) {
$new_array[$working_array[0]][] = $working_array[1]; }
Which would give you an array something like :
$new_array["joint_temps5"]=> array(2) {
[0]=> "23.5"
[1]=> "23.5"}
If you needed to you could then parse that into an array in the format you desire quite easily.

Related

How to get part of array excluding one key in multidimensional array?

I'm grouping one multidimensional array by age.
This is my code:
$mEmployees = array (
array("name"=>"Pedro", "age"=>20, "ID"=>1111),
array("name"=>"Carlos", "age"=>15, "ID"=>2222),
array("name"=>"Susana", "age"=>20, "ID"=>3333),
array("name"=>"Carmen", "age"=>19, "ID"=>4444)
);
$byAge=array();
foreach ($mEmployees as $k => $oneItem) {
$byAge[$oneItem['age']][$k] = $oneItem;
}
var_dump($byAge);
That works fine as you can see below:
output:
array(3) {
[20]=>
array(2) {
[0]=>
array(3) {
["name"]=>
string(5) "Pedro"
["age"]=>
int(20)
["ID"]=>
int(1111)
}
[2]=>
array(3) {
["name"]=>
string(6) "Susana"
["age"]=>
int(20)
["ID"]=>
int(3333)
}
}
[15]=>
array(1) {
[1]=>
array(3) {
["name"]=>
string(6) "Carlos"
["age"]=>
int(15)
["ID"]=>
int(2222)
}
}
[19]=>
array(1) {
[3]=>
array(3) {
["name"]=>
string(6) "Carmen"
["age"]=>
int(19)
["ID"]=>
int(4444)
}
}
}
But in the results, the age key is redundant. I want to remove this key in the $byAge array.
I tried with array_slice, but it's not possible to indicate one irregular offset (the key age is in middle).
How I can achieve this easily for this result?
array(3) {
[20]=>
array(2) {
[0]=>
array(3) {
["name"]=>
string(5) "Pedro"
["ID"]=>
int(1111)
}
[2]=>
array(3) {
["name"]=>
string(6) "Susana"
["ID"]=>
int(3333)
}
}
[15]=>
array(1) {
[1]=>
array(3) {
["name"]=>
string(6) "Carlos"
["ID"]=>
int(2222)
}
}
[19]=>
array(1) {
[3]=>
array(3) {
["name"]=>
string(6) "Carmen"
["ID"]=>
int(4444)
}
}
}
Cache the age value in a variable and unset from $oneItem.
foreach ($mEmployees as $k => $oneItem) {
$age = $oneItem['age'];
unset($oneItem['age']);
$byAge[$age][$k] = $oneItem;
}
Demo: https://3v4l.org/pDDn5

Sort multiple array with same order

Below is example of my array
["value"]=>
array(16) {
[0]=>
string(5) "4"
[1]=>
string(4) "2"
[2]=>
string(4) "1"
[3]=>
string(4) "3"
}
["id"]=>
array(16) {
[0]=>
string(4) "four-id"
[1]=>
string(4) "two-id"
[2]=>
string(4) "one-id"
[3]=>
string(4) "three-id"
}
Now I am sorrting using array_multisort($arr["value"],SORT_NUMERIC, SORT_DESC); , which results in below output.
["value"]=>
array(16) {
[0]=>
string(5) "4"
[1]=>
string(4) "3"
[2]=>
string(4) "2"
[3]=>
string(4) "1"
}
["id"]=>
array(16) {
[0]=>
string(4) "four-id"
[1]=>
string(4) "two-id"
[2]=>
string(4) "one-id"
[3]=>
string(4) "three-id"
}
I want $arr["id"] to be sorted based on same sorting order of $arr["value"] like below
["id"]=>
array(16) {
[0]=>
string(4) "four-id"
[1]=>
string(4) "three-id"
[2]=>
string(4) "two-id"
[3]=>
string(4) "one-id"
}
You can use krsort
$array_1 = Array(4,2,1,3);
$array_2 = Array('four-id','two-id','one-id','three-id');
foreach ($array_1 as $key => $value) {
$array_merged[$value] = $array_2[$key];
}
krsort($array_merged);
foreach ($array_merged as $key => $value) {
$new_array_1[] = $key;
$new_array_2[] = $value;
}
echo '<pre>'.print_r( $new_array_1, true ).print_r( $new_array_2, true ).'</pre>';

Flatten multi dimension array but maintain keys?

I have the following:
[6199]=>
array(12) {
["Origin"]=>
array(3) {
["name"]=>
array(1) {
[0]=>
string(4) "Cuba"
}
["slug"]=>
array(1) {
[0]=>
string(27) "cuabn-havana-habanos-cigars"
}
["id"]=>
array(1) {
[0]=>
int(0)
}
}
["Filler"]=>
array(3) {
["name"]=>
array(2) {
[0]=>
string(9) "Dominican"
[1]=>
string(10) "Nicaraguan"
}
["slug"]=>
array(2) {
[0]=>
string(9) "dominican"
[1]=>
string(10) "nicaraguan"
}
["id"]=>
array(2) {
[0]=>
int(0)
[1]=>
int(1)
}
}
}
[6192]=>
array(11) {
["Origin"]=>
array(3) {
["name"]=>
array(1) {
[0]=>
string(9) "Nicaragua"
}
["slug"]=>
array(1) {
[0]=>
string(27) "nicaraguan-new-world-cigars"
}
["id"]=>
array(1) {
[0]=>
int(0)
}
}
["Filler"]=>
array(3) {
["name"]=>
array(2) {
[0]=>
string(9) "Java"
[1]=>
string(10) "Nicaraguan"
}
["slug"]=>
array(2) {
[0]=>
string(9) "java"
[1]=>
string(10) "nicaraguan"
}
["id"]=>
array(2) {
[0]=>
int(0)
[1]=>
int(1)
}
}
}
and my expected output is:
array(12) {
["Origin"]=>
array(3) {
["name"]=>
array(1) {
[0]=>
string(4) "Cuba".
[1]=>
string(9) "Nicaragua"
}
["slug"]=>
array(1) {
[0]=>
string(27) "cuabn-havana-habanos-cigars",
[0]=>
string(27) "nicaraguan-new-world-cigars"
}
["id"]=>
array(1) {
[0]=>
int(0)
}
}
["Filler"]=>
array(3) {
["name"]=>
array(2) {
[0]=>
string(9) "Dominican"
[1]=>
string(10) "Nicaraguan"
[2]=>
string(9) "Java"
}
["slug"]=>
array(2) {
[0]=>
string(9) "dominican"
[1]=>
string(10) "nicaraguan"
[3]=>
string(9) "java"
}
["id"]=>
array(2) {
[0]=>
int(0)
[1]=>
int(1)
}
}
See how it eliminates dupes and merges each array maintaining the "origin" key.
I've tried :
foreach ($resultterms as $keyname => $valuename){
foreach ($valuename as $keysub => $valuesub) {
foreach($valuesub['name'] as $keysubsub => $valuesubsub){
# code...
$prods_atts[$keysub]['name'][$keysubsub] = $valuesubsub;
$prods_atts[$keysub]['slug'][$keysubsub] = $valuesub['slug'][$keysubsub];
$prods_atts[$keysub]['id'][$keysubsub] = $valuesub['id'][$keysubsub];
}
}
}
where $resultterms is the original arrays but it's not working. I was wondering if there was a wonderful php function I could use to merge these instead of so many nested for each loops?
I believe you're just looking for array_merge_recursive.
call_user_func_array('array_merge_recursive', array_values($prod_atts));
call_user_func_array allows to transform an array into a list of arguments
array_values because in the end, you seem to want to get rid of the first layer of your array
In order to try it, could you post the var_export of your variable instead of the var_dump?
echo(var_export($prod_atts, true));
merge your array by any suggested method. After that you will get duplicated values. And you need save only the unique items
$new = array_merge_recursive($resultterms['6199'], $resultterms['6192']);
foreach($new['Origin'] as &$item) { $item = array_unique($item); }
foreach($new['Filler'] as &$item) { $item = array_unique($item); }

Group array row data by two columns creating a new 3-level structure

I have 1 arrays:
array(5) { // This is the keys on the CSV.
[0]=>
array(4) {
[0]=>
string(4) "user"
[1]=>
string(4) "date"
[2]=>
string(3) "md5"
[3]=>
string(4) "sha1"
}
[1]=>
array(4) {
[0]=>
string(4) "user1"
[1]=>
string(8) "02/02/15"
[2]=>
string(6) "123456"
[3]=>
string(5) "54321"
}
[2]=>
array(4) {
[0]=>
string(4) "user1"
[1]=>
string(8) "02/03/15"
[2]=>
string(6) "123456"
[3]=>
string(5) "54321"
}
[3]=>
array(4) {
[0]=>
string(5) "user2"
[1]=>
string(8) "02/02/15"
[2]=>
string(6) "112233"
[3]=>
string(6) "332211"
}
[4]=>
array(4) {
[0]=>
string(5) "user2"
[1]=>
string(8) "02/03/15"
[2]=>
string(6) "112244"
[3]=>
string(6) "332244"
}
}
So User 1 and User 2 each have a file that is MD5/SHA1 sum'd and checked.
I would like the data to turn from the above, to this:
array(3) {
["user"]=>
array(1) {
["date"]=>
array(2) {
[0]=>
string(3) "md5"
[1]=>
string(4) "sha1"
}
}
["user1"]=>
array(1) {
["02/02/15"]=>
array(2) {
[0]=>
string(6) "123456"
[1]=>
string(5) "54321"
}
["02/03/15"]=>
array(2) {
[0]=>
string(6) "123456"
[1]=>
string(5) "54321"
}
}
["user2"]=>
array(1) {
["02/02/15"]=>
array(2) {
[0]=>
string(6) "112233"
[1]=>
string(6) "332211"
}
["02/03/15"]=>
array(2) {
[0]=>
string(6) "112244"
[1]=>
string(6) "332244"
}
}
}
So far, I'm close. Here is my code:
<?php
error_reporting(E_ALL & ~E_NOTICE);
//Reading csv
$csv = array_map('str_getcsv',file('/var/www/sums.csv'));
debug($csv);
//User list
$userData = array();
foreach ($csv as $user) {
$ts = $user[1];
$un = $user[0];
$sums = array($user[2],$user[3]);
$userPreProc[$un] = array($ts => $sums);
$userData = array_merge($userPreProc, $userData);
}
debug($userData);
function debug($db) {
echo "<pre>";
var_dump($db);
echo "</pre>";
}
?>
The issue here is that only the first 'user1' and 'user2' entries are merged to the new array, so it looks like this:
array(3) {
["user"]=>
array(1) {
["date"]=>
array(2) {
[0]=>
string(3) "md5"
[1]=>
string(4) "sha1"
}
}
["user1"]=>
array(1) {
["02/02/15"]=>
array(2) {
[0]=>
string(6) "123456"
[1]=>
string(5) "54321"
}
}
["user2"]=>
array(1) {
["02/02/15"]=>
array(2) {
[0]=>
string(6) "112233"
[1]=>
string(6) "332211"
}
}
}
Any suggestions how I can ensure that all the keys are merged as expected?
Just shift off the first two elements and use those respective values as the first and second level keys.
Code: (Demo)
$result = [];
foreach ($array as $row) {
$result[array_shift($row)][array_shift($row)] = $row;
}
var_export($result);
Or use array destructuring in the foreach declaration: (Demo)
$result = [];
foreach ($array as [$user, $date, $md5, $sha1]) {
$result[$user][$date] = [$md5, $sha1];
}
var_export($result);
Just change your foreach loop to be like this. You don't need to merge your array via function.
foreach ($csv as $user) {
$ts = $user[1];
$un = $user[0];
$sums = array($user[2],$user[3]);
$userData[$un][$ts] = $sums;
}

Is there a function to combine these arrays in php?

Given arrays 'a1' and 'b1' how may they be combined them to produce the final array? Basically replacing the value within 'a1' with the array data for the matching value within 'b1'. I guess the question would be if there is a function that can do this that I'm not seeing.
$a1 = array('id1'=>array('a'=>'444-444',
'b'=>'222-222',
'c'=>'111-111'),
'id2'=>array('a'=>'888-888',
'b'=>'666-666',
'c'=>'555-555')
);
$b1 = array('222-222'=>array('first'=>array('9999',
'dddd',
'yyyy'),
'second'=>'mmgghh'
),
'666-666'=>array('first'=>array('bbbb',
'cccc',
'7777'),
'second'=>'ffffgggg'
)
);
Desired combination:
array(2) {
["id1"]=>
array(3) {
["a"]=>
string(7) "444-444"
["b"]=>
array(1) {
["222-222"]=>
array(2) {
["first"]=>
array(3) {
[0]=>
string(4) "9999"
[1]=>
string(4) "dddd"
[2]=>
string(4) "yyyy"
}
["second"]=>
string(6) "mmgghh"
}
}
["c"]=>
string(7) "111-111"
}
["id2"]=>
array(3) {
["a"]=>
string(7) "888-888"
["b"]=>
array(1) {
["666-666"]=>
array(2) {
["first"]=>
array(3) {
[0]=>
string(4) "bbbb"
[1]=>
string(4) "cccc"
[2]=>
string(4) "7777"
}
["second"]=>
string(6) "ffffgggg"
}
}
["c"]=>
string(7) "555-555"
}
}
array_walk_recursive($a1,function(&$value,$key,$addin){
if(is_scalar($value) && isset($addin[$value])){
$value = array($value=>$addin[$value]);
}
},$b1);

Categories