PHP multidimensional associative array [duplicate] - php

This question already has answers here:
Transposing multidimensional arrays in PHP
(12 answers)
Closed 3 months ago.
I am new to php & I'm not sure that this can be done, but I am hoping that someone knows how to. I've collected all the data that I need to submit but now I need to reformat it before I can json_encode to send to the database.
Basically, I have 1 parent array($data) containing 3 sub-arrays ($hours, $WId, $Pid). I need to create associative arrays for each index position & join them together.
Here is my parent array:
$data = array(
'hours' => array(),
'wId' => array(),
'phaseId' => array(),
);
Here is what currently returns when I print_r each of these arrays:
Array ( [hours] => Array ( [0] => 0.5 [1] => 1 [2] => 2 ) )
Array ( [wId] => Array ( [0] => 10, [1] => 9, [2] => 8, ) )
Array ( [phaseId] => Array ( [0] => 20, [1] => 20, [2] => 19, ) )
I need to take these "vertical" arrays & turn them in to "horizontal" arrays per index, using thearray name as the $key & the value for that index as $value. Here is what I need to return.... (Syntax is probably wrong but you can get the idea.)
Array[1] ("hours" => 0.5, "wId" => 10, "phaseId" => 20)
Array[2] ("hours" => 1, "wId" => 9, "phaseId" => 20)
Array[3] ("hours" => 2, "wId" => 8, "phaseId" => 19)
Is there a function that will allow me to do this easily? I saw how to join & merge them together but not sure how to set the array name (hours, etc) as the $key & the value for each index as $value. I need to loop it too because the length of the arrays will vary. (But they will always the same length as each other, so index should still work as what needs to be collected.)
Any suggestions would be greatly appreciated :)

<?php
// set up your output array
$result = array();
// loop through $data, exposing $name for later use
foreach ($data as $name => $array) {
// loop through each named array and set the desired value
// using the current $key and $name
foreach ($array as $key => $value) {
$result[$key][$name] = $value;
}
}
// tada!
print_r($result);
NOTE: In your desired results in your question, you had the parent Array keys starting at 1. This answer assumes that's a typo and you actually wanted them to match the input. If you indeed wanted it to start at one, just change this line in my answer:
$result[$key+1][$name] = $value;

Related

Converting single array into multi dimensional array (grouping ) based on key

Lets say I have the following array:
$arr = array("exercise__2" => "Then a set", "sets__2" => 3, "exercise__4" => "And finally a set", "sets__4" => 3);
What I'm now trying to do is to convert this array into a multidimensional array every time the number changes in the key.
I know we have to use explode("__", $key), but I can't work out how to convert it to a multidimensional array so it would appear something like the following:
Array
(
Array
(
[exercise__2] => Then a set
[sets__2] => 3
)
Array
(
[exercise__4] => And finally a set
[sets__4] => 3
)
)
I suspect it's not too difficult but I'm frying my brain trying to work it out.
Simple for loop should do it:
$arr = array("exercise__2" => "Then a set", "sets__2" => 3, "exercise__4" => "And finally a set", "sets__4" => 3);
foreach($arr as $k =>$v) {
$res[explode("__", $k)[1]][$k] = $v;
}
You can use array_values if you don't want the extra key in the upper array.
Live example: 3v4l
Array_chunk seems to be enough.
Array_chunk splits an array with n number of items.
The third argument is to preserve keys.
$arr = array("exercise__2" => "Then a set", "sets__2" => 3, "exercise__4" => "And finally a set", "sets__4" => 3);
$result = array_chunk($arr, 2, true);
print_r($result);
Output:
Array
(
[0] => Array
(
[exercise__2] => Then a set
[sets__2] => 3
)
[1] => Array
(
[exercise__4] => And finally a set
[sets__4] => 3
)
)
https://3v4l.org/s57ua

Get values of array using as key values of another array

I have an array with some values (numeric values):
$arr1 = [1, 3, 8, 12, 23]
and I have another associative array that a key (which matches to a value of $arr1) correspond to a value. This array may contain also keys that don't match with $arr1.
$arr2 = [1 => "foo", 2 => "foo98", 3 => "foo20", 8 => "foo02", 12 => "foo39", 15 => "foo44", 23 => "foo91", 34 => "foo77"]
I want as return the values of $arr2 specifying as key the values of $arr1:
["foo", "foo20", "foo02", "foo39", "foo91"]
If possible, all this, without loops, using just PHP array native functions (so in an elegant way), or at least with the minimum number of loops possible.
Minimal loop is simple - 1. as:
foreach($arr1 as $k) {
$res[] = $arr2[$k];
}
You can do that with array_walk but I think this simple way is more readable.
If you insist you can do with array_filter + array_values + in_array as:
$res = array_values(array_filter($arr2,
function ($key) use ($arr1) { return in_array($key, $arr1);},
ARRAY_FILTER_USE_KEY
));
You can see this for more about filtering keys
To do it purely with array functions, you could do it as...
print_r(array_intersect_key($arr2, array_flip($arr1) ));
So array_flip() turns the items you want form the array into the keys for $arr1 and then uses array_intersect_key() to match the keys with the main array and this newly created array.
Gives...
Array
(
[1] => foo
[3] => foo20
[8] => foo02
[12] => foo39
[23] => foo91
)
If you don't want the keys - add array_values() around the rest of the calls...
print_r(array_values(array_intersect_key($arr2, array_flip($arr1) )));
to get
Array
(
[0] => foo
[1] => foo20
[2] => foo02
[3] => foo39
[4] => foo91
)
Although as pointed out - sometimes a simple foreach() is just as good and sometimes better.

Sum of array values based on similar values from another array

This might be a little confusing, but I am going to explain it as best as I can. Please bear with me.
I have the following arrays:
Array
(
[question1] => 69
[question2] => 36
[question3] => 57
[question4] => 69
[question5] => 58
[question6] => 40
[question7] => 58
)
Array
(
[question1] => 8
[question2] => 6
[question3] => 5
[question4] => 6
[question5] => 7
[question6] => 8
[question7] => 5
)
As you can see the two arrays have identical keys, but different values for each key.
I need to find the keys in the second array that have the same values, so [question1] and [question6] both have a value of 8. And then in the first array I need to add together the values of [question1] and [question6] because they have a like value in the second array. I need to add the first array values together based on matching values in the second array (if that makes any sense)
Ideally, the output would be another array that would look something like this:
Array
(
[5] => 115
[8] => 109
[6] => 105
[7] => 58
)
Where the value of the second array becomes the key and the sum of the added values from the first array is the value.
Now I won't be picky here, so if we can't get it into that exact format then that is okay. I just need to be able to add together the values in the first array based on the similar values in the second array.
I hope this makes sense. If it doesn't please comment and I will do my best to explain further.
The simplest solution is to iterate over the second array. Lookup the key into the first array and if it exists then add the corresponding value from the first array into the result array, indexed by the value from the second array.
Something like this:
$array1 = array(
'question1' => 69,
'question2' => 36,
'question3' => 57,
'question4' => 69,
'question5' => 58,
'question6' => 40,
'question7' => 58,
);
$array2 = array(
'question1' => 8,
'question2' => 6,
'question3' => 5,
'question4' => 6,
'question5' => 7,
'question6' => 8,
'question7' => 5,
);
// Compose the desired result here
$result = array();
// Iterate over the second array; its values become keys in the result array
foreach ($array2 as $key => $val) {
// If this is the first time when this value is reached then a corresponding
// value does not yet exists in the result array; add it
if (! isset($result[$val])) {
$result[$val] = 0;
}
// Lookup the key into the first array
if (isset($array1[$key])) {
// If it exists then add its value to the results
$result[$val] += $array1[$key];
}
}
// That's all
print_r($result);

I honestly have no clue how to formulate this pass-by-reference conundrum

So here's what I see this code doing:
An array is made
A loop iterates 10 times
A new array is created
A reference to this new array is saved in the first array
10 arrays now reside in the original array with values 0, 1, 2, 3...
What really happens:
WTF?
Code:
<?php
header('Content-type: text/plain');
$arrays = array();
foreach(range(0, 10) as $i)
{
$arr = array();
$arr[0] = $i;
$arrays[] = &$arr;
}
print_r($arrays);
Output:
Array
(
[0] => Array
(
[0] => 10
)
[1] => Array
(
[0] => 10
)
[2] => Array
(
[0] => 10
)
[3] => Array
(
[0] => 10
)
[4] => Array
(
[0] => 10
)
[5] => Array
(
[0] => 10
)
[6] => Array
(
[0] => 10
)
[7] => Array
(
[0] => 10
)
[8] => Array
(
[0] => 10
)
[9] => Array
(
[0] => 10
)
[10] => Array
(
[0] => 10
)
)
I would like to know exactly why apparently only the 10th array is referred to ten times, instead of every instance of the arrays being referred to one each.
Also if somebody who isn't just thinking WTF (like me) would like to edit the title, feel free to do so.
The line
$arr = array();
does not create a new array but rather assigns an empty array to the already existing reference.
If you want the variable name to "point" to a different array in memory, you have to unset() (or "disconnect") it first before assigning an empty array to it:
foreach(range(0, 10) as $i)
{
unset($arr);
$arr = array();
$arr[0] = $i;
$arrays[] = &$arr;
}
This is because the only operations that can make a variable point to something else is the reference assignment (=&) and the unset().
What happens here is that by inserting a reference to $arr inside $arrays, you are effectively adding the exact same array 10 times -- and each reference to the array has the value last assigned to it (i.e. the one produced when $i is 10).
It's not clear what you intend to achieve by inserting a reference in each iteration -- either removing the & or putting unset($arr) at the beginning of the loop would give you the expected behavior. What are you trying to accomplish?
Think about it this way. You do $arrays[] = &$arr; 10 times. This stores a reference to the local variable $arr 10 times. Since it's the same variable (the variable's scope is the entire function), it stores the same reference all 10 times. Thus, why should you expect the 10 elements to be different?
The reference you are storing has nothing to do with the value of $arr; it just has to do with the variable $arr. When you print the reference it prints the value of $arr at that time.
It's because you're storing a reference to the array that $arr points to in the array. And you keep overwriting that array with the latest number. All references in $arr will point to the same array in the end.
I don't know what you expect to get out of this in the end, but getting rid of & should fix this behavior.

Fetching a multidimensional array

I am trying to edit a plugin that is fetching a multidimensional array, then breaking it out into a foreach statement and doing stuff with the resulting data.
What I am trying to do is edit the array before it gets to the foreach statement. I want to look and see if there is a key/value combination that exists, and if it does remove that entire subarray, then reform the array and pass it to a new variable.
The current variable
$arrayslides
returns several subarrays that look like something like this (I remove unimportant variables for the sake of briefness):
Array (
[0] => Array (
[slide_active] => 1
)
[1] => Array (
[slide_active] => 0
)
)
What I want to do is look and see if one of these subarrays contains the key slide_active with a value of 0. If it contains a value of zero, I want to dump the whole subarray altogether, then reform the multidimensional array back into the variable
$arrayslides
I have tried a few array functions but have not had any luck. Any suggestions?
$arrayslides = array(0 => array ( 'slide_active' => 1, 'other_data' => "Mark" ),
1 => array ( 'slide_active' => 0, 'other_data' => "ABCDE" ),
2 => array ( 'slide_active' => 1, 'other_data' => "Baker" ),
3 => array ( 'slide_active' => 0, 'other_data' => "FGHIJ" ),
);
$matches = array_filter($arrayslides, function($item) { return $item['slide_active'] == 1; } );
var_dump($matches);
PHP >= 5.3.0
I know its not so efficient but still
foreach ($arraySlides as $key => $value)
{
if(in_array('0', array_values($value))
unset($arraySlides[$key]);
}

Categories