Convert single array into multidimensional array in PHP? - php

If I have this array in PHP:
array(3) {
[0]=>
string(5) "first"
[1]=>
string(6) "second"
[2]=>
string(5) "third"
}
How can I convert this single array into a multidimensional array? What is the quickest way? So I can access this array like:
$array["first"]["second"]...
I want to be able to then set a value to this index like:
$array["first"]["second"]["third"] = "example";
I thought that I need a for loop or a recursive function but I have no idea how to start.

It wasn't quite as simple as I had imagined to begin with. The key to it was doing the process backwards - starting with the last array and then wrapping it in more arrays until you get back to the top level.
$array = array("first", "second", "third");
$newArr = array();
//loop backwards from the last element
for ($i = count($array)-1; $i >= 0 ; $i--)
{
$arr = array();
if ($i == count($array)-1) {
$val = "example";
$arr[$array[$i]] = $val;
}
else {
$arr[$array[$i]] = $newArr;
}
$newArr = $arr;
}
var_dump($newArr);
echo "-------".PHP_EOL;
echo $newArr["first"]["second"]["third"];
Demo: http://sandbox.onlinephpfunctions.com/code/0d7fa30fde7126160fbcc0e80e5727f17b19e39f

Related

Php group repeated array values

How to group repeated array values in an array using PHP?
I have an array like this
array[0]=203,
array[1]=204,
array[2]=204,
array[3]=203,
array[4]=203,
array[5]=205
I need results like
[203]=1,
[204]=2,
[203]=2,
[205]=1
i want the count of continuously repeating array values
One option to your expected output is to create a indexed array with the associative array below it.
This will create this kind of array:
array(4) {
[0]=>
array(1) {
[203]=>
int(1)
}
[1]=>
array(1) {
[204]=>
int(2)
}
[2]=>
array(1) {
[203]=>
int(2)
}
[3]=>
array(1) {
[205]=>
int(1)
}
}
This is not what you wanted but it is what is possible.
The code loops and keeps track of what the previous value is, if it's the same it will count up the value, else create a new indexed and associative array with value 1.
$array =[203,204,204,203,203,205];
$i=-1;
$prev = null;
$new=[];
foreach($array as $val){
if($val != $prev){
$i++;
}
if(!isset($new[$i][$val])){
$new[$i][$val] =1;
}else{
$new[$i][$val]++;
}
$prev = $val;
}
var_dump($new);
https://3v4l.org/W2adN
array[0]=203;
array[1]=204;
array[2]=204;
array[3]=203;
array[4]=203;
array[5]=205;
$new_array = array();
foreach ($array as $key => $value) {
if(empty($new_array[$value])){
$new_array[$value] = 1;
}else{
$new_array[$value]++;
}
}
/*Now in the array $new_array you have the count of continuously repeating array values*/
This can be done in one line of code using array_count_value function in php.
$arr[0]=203;
$arr[1]=204;
$arr[2]=204;
$arr[3]=203;
$arr[4]=203;
$arr[5]=205;
$result = array_count_values( $arr );
var_dump( $result );
output
array (size=3)
203 => int 3
204 => int 2
205 => int 1

PHP get ranges of same values from array

Is there any way to get the key range of same values and make a new array?
Let's say we have an Array Like this in php :
$first_array = ['1'=>'a','2'=>'a','3'=>'a','4'=>'b','5'=>'b','6'=>'a','7'=>'a'];
How can i get this array? Is there any function for this?
$second_array = ['1-3'=>'a','4-5'=>'b','6-7'=>'a'];
Loop through it, extract the keys, generate the ranges and insert to the new array -
$first_array = ['1'=>'a','2'=>'a','3'=>'a','4'=>'b','5'=>'b'];
$flip = array();
foreach($first_array as $key => $val) {
$flip[$val][] = $key;
}
$second_array = [];
foreach($flip as $key => $value) {
$newKey = array_shift($value).' - '.end($value);
$second_array[$newKey] = $key;
}
Output
array(2) {
["1 - 3"]=>
string(1) "a"
["4 - 5"]=>
string(1) "b"
}
regarding your first question you can get range of each value using foreach() loop.
$first_array = ['1'=>'a','2'=>'a','3'=>'a','4'=>'b','5'=>'b'];
foreach($first_array as $key=>$value)
{
//do your coding here, $key is the index of the array and $value is the value at that range, you can use that index and value to perform array manipulations
}
Regarding your second question it not exactly clear what are trying to implement there. But what ever you want to do like creating a new array with modified index and other things can be done within this foreach() loop itself
I hope this helps you.
If someone is still looking for an answer, here is what I did.
Given the array
$first_array = ['0'=>'a',
'1'=>'a',
'2'=>'a',
'3'=>'a',
'4'=>'a',
'5'=>'b',
'6'=>'b',
'7'=>'a',
'8'=>'a']
I build a multidimensional array, in which each element is an array of three more elements:
[0] - The value in the first array
[1] - The key where the value starts repeating
[2] - The last key where the value stops repeating
The code
$arrayRange = [];
for($i = 0; $i < count($first_array); $i++){
if(count($arrayRange) == 0){
// The multidimensional array is still empty
$arrayRange[0] = array($first_array[$i], $i, $i);
}else{
if($first_array[$i] == $arrayRange[count($arrayRange)-1][0]){
// It's still the same value, I update the value of the last key
$arrayRange[count($arrayRange)-1][2] = $i;
}else{
// It's a new value, I insert a new array
$arrayRange[count($arrayRange)] = array($first_array[$i], $i, $i);
}
}
}
This way you get a multidimensional array like this:
$arrayRange[0] = array['a', 0, 4];
$arrayRange[1] = array['b', 5, 6];
$arrayRange[2] = array['a', 7, 8];

Changing values of multidimensional array php

Its my first time working with multidimensional arrays in php. I need to change the second number in each sub array.
What I want is to check if the Id in the array matches the Id from the database. When the two match I want to change the 2nd entry in the sub array by adding a number to it. If the Id from the query does not match anything in the list I want a new sub array to be pushed to the end of the array with the values of Id and points_description.
Also, if its helpful, my program right now does find the matches. The only thing is, it does not update the 2D array.
$array = array(array());
while ($row_description = mysqli_fetch_array($query_description)) {
$check = 1;
$is_match = 0;
foreach ($array as $i) {
foreach ($i as $value) {
if ($check == 1) {
if ($row_description['Id'] == $value) {
//$array[$i] += $points_description;
$is_match = 1;
}
}
$check++;
$check %= 2; //toggle between check and points
}
}
if ($is_match == 0) {
array_push($array, array($row_description['Id'], $points_description));
}
}
I feel like Im doing this so wrong. I just want to go through my 2D array and change every second value. The expected output should be a print out of all the Ids and their corresponding point value
I hope this is helpful enough.
Example: $row_description['Id'] = 2 and $array = array(array(2,1), array(5,1) , array(6,1))
output should be $array = array(array(2,4), array(5,1) , array(6,1))
if $row_description['Id'] = 3 and $array = array(array(2,1), array(5,1) , array(6,1))
output should be $array = array(array(2,4), array(5,1) , array(6,1),array(3,3))
By default PHP will copy an array when you use it in a foreach.
To prevent PHP from creating this copy you need to use to reference the value with &
Simple example :
<?php
$arrFoo = [1, 2, 3, 4, 5,];
$arrBar = [3, 6, 9,];
Default PHP behavior : Make a copy
foreach($arrFoo as $value_foo) {
foreach($arrBar as $value_bar) {
$value_foo *= $value_bar;
}
}
var_dump($arrFoo);
/* Output :
array(5) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
}
*/
ByReference : Don't create the copy :
foreach($arrFoo as &$value_foo) {
foreach($arrBar as $value_bar) {
$value_foo *= $value_bar;
}
}
var_dump($arrFoo);
/* Output :
array(5) {
[0]=>
int(162)
[1]=>
int(324)
[2]=>
int(486)
[3]=>
int(648)
[4]=>
&int(810)
}
*/

Shuffle 2 php arrays in the same way

I have this for example:
$array['one'][0] = 0;
$array['one'][1] = 1;
$array['one'][2] = 2;
$array['one'][3] = 3;
$array['two'][0] = 00;
$array['two'][1] = 11;
$array['two'][2] = 22;
$array['two'][3] = 33;
How can I shuffle them both to get something like:
$array['one'][0] = 2;
$array['one'][1] = 1;
$array['one'][2] = 3;
$array['one'][3] = 0;
$array['two'][0] = 22;
$array['two'][1] = 11;
$array['two'][2] = 33;
$array['two'][3] = 00;
Or any other random order, but having the same "random factor" in both?
For example, I want that $array['one'][0] and $array['two'][0] get shuffled to get $array['one'][x] and $array['two'][x] (x being a random key, but the SAME on both arrays).
$count = count($array['one']);
$order = range(1, $count);
shuffle($order);
array_multisort($order, $array['one'], $array['two']);
Works with arrays with elements of any type (objects and arrays too).
This way may by used with any number of arrays (not only two).
Works with duplicated values.
Clean code.
Something like this could work. It's similar to Mimikry's answer except this one will work even if you happen to have duplicate values in array one (this one doesn't use values of array one as keys of the temporary array).
Assuming both arrays are of the same size.
$c = count($array['one']);
$tmp = array();
for ($i=0; $i<$c; $i++) {
$tmp[$i] = array($array['one'][$i], $array['two'][$i]);
}
shuffle($tmp);
for ($i=0; $i<$c; $i++) {
$array['one'][$i] = $tmp[$i][0];
$array['two'][$i] = $tmp[$i][1];
}
hopefully i get you right.
For your example above, this code should work. But it's pretty hacky...
$array['one'][0] = 'A';
$array['one'][1] = 'B';
$array['one'][2] = 'C';
$array['one'][3] = 'D';
$array['two'][0] = 'AA';
$array['two'][1] = 'BB';
$array['two'][2] = 'CC';
$array['two'][3] = 'DD';
// save the dependencies in tmp array
foreach ($array['two'] as $key => $val) {
$tmp[$array['one'][$key]] = $val;
}
shuffle($array['one']);
// restore dependencies in tmp2 array
foreach ($array['one'] as $key => $val) {
$tmp2[$key] = $tmp[$val];
}
// overwrite with restore array
$array['two'] = $tmp2;
var_dump($array):
array(2) {
["one"]=>
array(4) {
[0]=>
string(1) "B"
[1]=>
string(1) "A"
[2]=>
string(1) "C"
[3]=>
string(1) "D"
}
["two"]=>
array(4) {
[0]=>
string(2) "BB"
[1]=>
string(2) "AA"
[2]=>
string(2) "CC"
[3]=>
string(2) "DD"
}
}
The best practice, imho, is as follows:
$tmp = array_combine($array['one'],$array['two']);
shuffle($tmp);
$array['one'] = array_keys($tmp);
$array['two'] = array_values($tmp);
This is clear code and should be fast. No need to reinvent the wheel like in some other answers.
This isn't an example with multidimensional arrays but it works great for sorting multiple normal arrays the same way and with shuffle. Maybe it could be adapted for multidimensional arrays too. It does assume all arrays are the same length.
$array_count = count($array_1);
for($i=0;$i<=($array_count-1);$i++){
$temp_array[$i] = $i;
}
shuffle($temp_array);
for($i=0;$i<=($array_count-1);$i++){
$o = $temp_array[$i];
$array_1_sorted[$i]=$array_1[$o];
$array_2_sorted[$i]=$array_2[$o];
$array_3_sorted[$i]=$array_3[$o];
}
This will give you new arrays which are all sorted the same random way. You could then set the old arrays equal to the new ones or keep them in-tact.
Not sure exactly what you are trying to do, but your best bet is probably to put array 1 and array 2 into a multi-dimensional array and then random the primary array. That will give you a random arrangement of values, but within each key will be the values of each array. We could give you more specific answers if you can provide a bit more detail of exactly what you are doing.

php pushing pattern from array1 to array2

I have an array that looks something like this
array(7) {
[0]=> "hello,pat1"
[1]=> "hello,pat1"
[2]=> "test,pat2"
[3]=> "test,pat2"
[4]=> "foo,pat3"
[5]=> "foo,pat3"
[6]=> "foo,pat3"
....
}
I would like to push it into another array so the output of the array2 is as follow:
array(7) {
[0]=> "hello,pat1"
[1]=> "test,pat2"
[2]=> "foo,pat3"
[3]=> "foo,pat3"
[4]=> "foo,pat3"
[5]=> "hello,pat1"
[6]=> "test,pat2"
.....
}
What I want is to push them in the following pattern: 1 "pat1" 1 "pat2" and 3 "pat3", and repeat this pattern every 5 elements.
while ( !empty( $array1 ) )
$a = explode(",",$array1[$i]);
if($a[1]=='pat1' &&)
push && unset
elseif($a[1]=='pat2' &&)
push && unset
elseif($a[1]=='pat3' and < 5)
push && unset and reset pattern counter
}
What would be a good way of doing this?
Any idea will be appreciate it.
Time for some fun with the iterators of the Standard PHP Library :-)
<?php
$array1 = array (
"hello1,pat1", "hello2,pat1", "hello3,pat1",
"test1,pat2", "test2,pat2",
"foo1,pat3", "foo2,pat3", "foo3,pat3",
"foo4,pat3", "foo5,pat3", "foo6,pat3"
);
// "group by" patN
$foo = array();
foreach($array1 as $a) {
// feel free to complain about the # here ...to somebody else
#$foo[ strrchr($a, ',') ][] = $a;
}
// split pat3 into chunks of 3
$foo[',pat3'] = array_chunk($foo[',pat3'], 3);
// add all "groups" to a MultipleIterator
$mi = new MultipleIterator(MultipleIterator::MIT_NEED_ANY);
foreach($foo as $x) {
$mi->attachIterator( new ArrayIterator($x) );
}
// each call to $mi->current() will return an array
// with the current items of all registered iterators
foreach ($mi as $x) {
// "flatten" the nested arrays
foreach( new RecursiveIteratorIterator(new RecursiveArrayIterator($x)) as $e) {
echo $e, "\n";
}
echo "----\n";
}
I think I'd set respective counters with respective incrementation. Since php will cast float keys to integers, you can just increment the ,pat3 items with .33 instead of 1. Then, to flatten the result, just use array_merge() with the splat operator.
Code: (Demo)
$array = [
"hello1,pat1",
"hello2,pat1",
"test3,pat2",
"test4,pat2",
"foo5,pat3",
"foo6,pat3",
"foo7,pat3",
];
$counters = [',pat1' => 0, ',pat2' => 0, ',pat3' => 0];
foreach ($array as $value) {
$end = strrchr($value, ',');
$groups[$counters[$end]][] = $value;
$counters[$end] += ($end === ',pat3' ? .33 : 1);
}
var_export(array_merge(...$groups));
Output:
array (
0 => 'hello1,pat1',
1 => 'test3,pat2',
2 => 'foo5,pat3',
3 => 'foo6,pat3',
4 => 'foo7,pat3',
5 => 'hello2,pat1',
6 => 'test4,pat2',
)

Categories