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
I have a string which has "23:22:0"
$string = "23:22:0";
$array = explode(":", $string);
if ($array[0] == 0) {
$array[0] = 1;
}
if ($array[1] == 0) {
$array[1] = 1;
}
if ($array[2] == 0) {
$array[2] = 1;
}
How to avoid multiple if condition check here and i need this condition to be optimised in some best way. Any help is appreciated thanks in advance.
Please check below example. I have commented out your $string variable and tested $string with '0:0:0' value.
Added print_r() to check whether the value is correct or not as we are expecting.
Hope it might be helpful.
//$string = "23:22:0";
$string = "0:0:0";
$array = explode(":", $string);
$array = array(
0 => ($array[0] == 0) ? 1 : $array[0],
1 => ($array[1] == 0) ? 1 : $array[1],
2 => ($array[2] == 0) ? 1 : $array[2],
);
print_r($array);
I wrote this answer because I thought there was an unknown number of items.
OP has now clarified that it's always three items. This is probably a bit overkill for the task at hand.
You can create a new array with 1's and use array_replace to merge it with the original array if you first remove the zero values.
$string = "23:22:0";
$array = explode(":", $string);
$fill = array_fill(0,count($array), 1); //create new array [1,1,1]
$array= array_filter($array); // remove zero values
$array= array_replace($fill,$array); // "merge" the arrays
var_dump($array);
Output:
array(3) {
[0]=>
string(2) "23"
[1]=>
string(2) "22"
[2]=>
int(1)
}
https://3v4l.org/thpfU
With three items in mind you can make the code look better with a loop.
It will perform about the same I believe.
foreach($array as &$val){
if(!$val) $val=1;
}
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)
}
*/
The title of this questions sounds a bit confusing, but I don't know how I should call it, so I will explain it further:
For example I got the following array:
[0]=> "id" [1]=> "5" [2]=> "value" [3]=> "8"
And so on, this array could be endless, but the number of content is even.
Now I want to have this array converted into an associative array where on pair is index => value. Like this:
[id] = "5" [value] = "8"
I thought about, that I foreach the array twice: first I set the indexes if count is odd and second I reset index and set the value if count is even. But there must be a better approach to do this.
Thanks for you help.
$array = array("id", "5", "value", "8");
$new_array = array();
for ($i = 1; $i < count($array); $i+=2) {
$new_array[$array[$i - 1]] = $array[$i];
}
The following code should serve your purpose:
$arr = array("id", "5", "value", "8");
$size = sizeof($arr);
$_arr = array();
for($i = 0; $i < $size; $i+=2){
$_arr[$arr[$i]] = $arr[$i+1];
}
DEMO
Why not a multidimensional array?
$arr = array(
array("id", "5"),
array("value", "8")
);
I need some help/direction in setting up a PHP script to randomly pair up items in an array.
The items should be randomly paired up each time.
The items should not match themselves ( item1-1 should not pair up with item1-1 )
Most of the items have a mate (ie. item1-1 and item1-2). The items should not be paired with their mate.
I've been playing around with the second script in this post but, I haven't been able to make any progress. Any help is appreciated.
Very simple approach, but hopefully helpful to you:
(mates, if grouped in an array (e.g. array('a1', 'a2')), will not be paired.)
function matchUp($array) {
$result = array();
while($el = array_pop($array)) {
shuffle($array);
if (sizeof($array) > 0) {
$candidate = array_pop($array);
$result[] = array(
array_pop($el),
array_pop($candidate)
);
if (sizeof($el) > 0) {
$array[] = $el;
}
if (sizeof($candidate) > 0) {
$array[] = $candidate;
}
}
else {
$result[] = array(array_pop($el));
}
}
return $result;
}
$array = array(
array('a1', 'a2'),
array('b1', 'b2'),
array('c1'),
array('d1'),
array('e1', 'e2'),
array('f1'),
array('g1', 'g2'),
);
Update:
foreach(matchUp($array) as $pair) {
list($a, $b) = $pair + array(null, null);
echo '<div style="border: solid 1px #000000;">' . $a . ' + ' . $b . '</div>';
}
With the randomness, there is no guarantee that a full correct solution will be reached.
Certain problem sets are more likely to be solved than others. Some will be impossible.
You can configure how many times it will try to achieve a good solution. After the specified number of tries it will return the best solution it could find.
function pairUp (array $subjectArray) {
// Config options
$tries = 50;
// Variables
$bestPaired = array();
$bestUnpaired = array();
for($try = 1; $try <= 50; $try++) {
$paired = array();
$unpaired = array();
$toBePaired = $subjectArray;
foreach($subjectArray as $subjectIndex => $subjectValue) {
// Create array without $thisValue anywhere, from the unpaired items
$cleanArray = array();
foreach($toBePaired as $index => $value) {
if($value != $subjectValue) {
array_push($cleanArray, array(
'index' => $index,
'value' => $value
));
}
}
sort($cleanArray); // reset indexes in array
// See if we have any different values left to match
if(count($cleanArray) == 0) {
array_push($unpaired, $subjectValue);
continue;
}
// Get a random item from the clean array
$randomIndex = rand(0,count($cleanArray)-1);
// Store this pair
$paired[$subjectIndex] = $subjectValue . '-' . $cleanArray[$randomIndex]['value'];
// This item has been paired, remove it from unpairedItems
unset($toBePaired[$cleanArray[$randomIndex]['index']]);
sort($toBePaired);
}
// Decide if this is our best try
if(count($paired) > count($bestPaired)) {
$bestPaired = $paired;
$bestUnpaired = $unpaired;
}
// If we had no failures, this was a perfect try - finish
if(count($unpaired) == 0) { $break; }
}
// We're done, send our array of pairs back.
return array(
'paired' => $bestPaired,
'unpaired' => $bestUnpaired
);
}
var_dump(pairUp(array('a','b','c','d','e','a','b','c','d','e')));
/*
Example output:
array(2) {
["paired"]=>
array(10) {
[0]=>
string(3) "a-b"
[1]=>
string(3) "b-c"
[2]=>
string(3) "c-d"
[3]=>
string(3) "d-e"
[4]=>
string(3) "e-a"
[5]=>
string(3) "a-b"
[6]=>
string(3) "b-e"
[7]=>
string(3) "c-d"
[8]=>
string(3) "d-c"
[9]=>
string(3) "e-a"
}
["unpaired"]=>
array(0) {
}
}
*/
Case 1: if all elements had a mate
If all elements had a mate, the following solution would work, although I don't know if it would be perfectly random (as in, all possible outputs having the same probability):
Shuffle the list of elements, keeping mates together
original list = (a1,a2),(b1,b2),(c1,c2),(d1,d2)
shuffled = (c1,c2),(d1,d2),(a1,a2),(b1,b2)
Shift the second mate to the right. The matches have been formed.
shifted = (c1,b2),(d1,c2),(a1,d2),(b1,a2)
(Edit1: if applied exactly as described, there is no way a1 ends up matched with b1. So, before shifting, you may want to throw a coin for each pair of mates to decide whether they should change their order or not.)
Case 2: if only some elements have a mate
Since in your question only some elements will have a mate, I guess one could come up with the following:
Arbitrarily pair up those elements who don't have a mate. There should be an even number of such elements. Otherwise, the total number of elements would be odd, so no matching could be done in the first place.
original list = (a1,a2),(b1,b2),c1,d1,e1,f1 // c1,d1,e1 and f1 don't have mates
list2 = (a1,a2),(b1,b2),(c1,d1),(e1,f1) // pair them up
Shuffle and shift as in case 1 to form the matches.
shuffled = (e1,f1),(a1,a2),(c1,d1),(b1,b2)
shifted = (e1,b2),(a1,f1),(c1,a2),(b1,d1)
Again, I don't know if this is perfectly random, but I think it should work.
(Edit2: simplified the solution)
(Edit3: if the total number of elements is odd, someone will be left without a match, so pick an element randomly at the beginning to leave it out and then apply the algorithm above).