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")
);
Related
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
This question already has answers here:
Show the two elements in foreach loop in every iteration? [duplicate]
(4 answers)
Closed 1 year ago.
This is my array:
$my_array = array("1", "2", "3", "4");
I want to achieve something like this:
1 vs 2
3 vs 4
Because the length of my array is only 4 it was easy for me to do this:
echo $my_array[0]." vs ".$my_array[1];
echo "<br>";
echo $my_array[2]." vs ".$my_array[3];
But how can I achieve this if my array has more than 100 values? I also want to account for odd numbers of array elements.
You can use a "for" loop, with an increment of two for every loop :
$len = count($my_array);
for($i=0; $i<$len; $i=$i+2) {
echo $my_array[$i]." vs ".$my_array[$i+1]."<br/>;
}
If you're not sure your array always contains an even number of indexes, you can add a condition in order to ignore the last case if there is no more pair to do.
$len = count($my_array);
for($i=0; $i<$len; $i=$i+2) {
if($i !== $len-1) {
echo $my_array[$i]." vs ".$my_array[$i+1]."<br/>;
}
}
Sure, for loop is the obvious answer, but there are more interesting ones ;)
$my_array = ["1", "2", "3", "4"];
$new_array = array_map(
function($v) {return isset($v[1]) ? "$v[0] vs $v[1]<br/>" : null; },
array_chunk($my_array, 2)
);
print_r($new_array);
Output:
Array
(
[0] => 1 vs 2<br/>
[1] => 3 vs 4<br/>
)
You can use a for loop to loop through the array.
$my_array = array("1", "2", "3", "4","5","6");
for ($x = 0; $x < sizeof($my_array); $x = $x+2) {
echo $my_array[0+$x]." vs ".$my_array[1+$x];
echo "<br>";
}
I have a mysql query object result which I want to parse through. Let's say the array looks like this.
$superheroes = array(
[0] => array(
"name" => "Peter Parker",
"email" => "peterparker#mail.com",
"age"=>"33",
"sex"=>"male",
),
[1] => array(
"name" => "jLaw",
"email" => "jlaw#mail.com",
"age"=>"22",
"sex"=>"female",
),
[2] => array(
"name" => "Clark Kent",
"email" => "clarkkent#mail.com",
"age"=>"36",
"sex"=>"male",
),
[3] => array(
"name" => "Gal Gadot",
"email" => "gal#mail.com",
"age"=>"22",
"sex"=>"female",
)
);
I want to iterate through this array, and while I am at each array, I want to look ahead in the next array, and find out the age difference between current male hero and next immediate female in the list. I found a lot of posts that talk about
1. array_keys
2. caching iterators,
3. prev, next, etc.
But all of them are talking about one dimensional arrays. Here Is what I tried
foreach ($superheroes as $key => $list){
if($list['sex']=="male"){
$currentHerosAge=$list['age'];
while($next=next($superheroes)){
if($next['sex']=="female"){
$diff=$currentHerosAge -$next['age'];
echo "Age diff: ".$diff;
break;
}
}
}
}
But when I try this, for array[0], next misses the array[1], and picks up array[3]. Not sure how to work this out.
You can use array_slice to slice array form the next key index and then look for the fist female age
$diff = [];
foreach($superheroes as $key => $male) {
if ($male['sex'] === 'female' ) continue;
// get the next key index
$nextKey = $key + 1;
if ( isset( $superheroes[ $nextKey ] ) ) {
// slice from the next key index
$nextSuperHeros = array_slice($superheroes, $nextKey);
foreach($nextSuperHeros as $k => $female) {
if ($female['sex'] === 'female') {
$diff[] = $male['age'] - $female['age'];
break;
}
}
}
}
A working Example
Hope this helps
Normally, you don't use a "lookahead", when iterating over the array. The common way would be to store the item of the last iteration and do the comparison on this element
$last_hero = false;
foreach ($superheroes as $hero) {
if ($last_hero) {
// do some stuff..
}
$last_hero = $hero;
}
If you really need a lookahead of more than one item, you wouldn't use a foreach loop.
for ($i = 0; $i < count($superheroes); $i++) {
// do sth. with $superheroes[$i]
if (...) {
for ($j = $i + 1; $j < count($superheroes); $j++) {
// do sth. with $superheroes[$j]
}
}
}
this code works, here's your solution for that situation (i will update explaining why) + editing the Clark - Gal part, one more comparison.
Execute it here if you like. this is a fancy version with echo's just to illustrate the running logic and what is happening inside the loops :) of course the final result can be much more simple.
<?php
$superheroes = [
[
"name" = "Peter Parker",
"email" = "peterparker#mail.com",
"age"="33",
"sex"="male",
],[
"name" = "jLaw",
"email" = "jlaw#mail.com",
"age"="22",
"sex"="female",
],[
"name" = "Clark Kent",
"email" = "clarkkent#mail.com",
"age"="36",
"sex"="male",
],[
"name" = "Gal Gadot",
"email" = "gal#mail.com",
"age"="22",
"sex"="female",
]
];
$length = count($superheroes);
$counterReset = 0;
while ($current = current($superheroes) )
{
$length -= 1;
if($current['sex']=="male"){
$currentHerosAge = $current['age'];
while($next = next($superheroes)){
$counterReset += 1;
if($next['sex']=="female"){
$diff=$currentHerosAge - $next['age'];
echo "\n C: ".$current['name']." to ".$next['name']." Age diff: ".$diff."\n";
break;
}
}
}
if($counterReset 0){
for($i = 0; $i < $counterReset; $i++){
prev($superheroes);
}
$counterReset = 0;
}
if($length == 0){
break;
}
next($superheroes);
}
current() next() prev() all act as pointers. Which means that every time you call them you control the movement of the assuming "head" of array or element you are calling. For this reason every time you move with next() you must make sure you also return back to the desired position in order to continue looping the regular loop :)
References next(), current(), prev() and reset()
execution logic
You declaration of the array or arrays was bringing a PHP Warning PHP Warning: Illegal offset type in /home/ on line 21 and was empty. For that reason I re-declared that way.
Given 2 associative arrays:
$fruits = array ( "d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple" );
$fruits2 = array ( "e" => "lemon", "f" => "apple", "g" => "melon", "h" => "apple" );
I would like to do something like:
for ( $n = count($fruits), $i = 0; $i < $n; $i++)
{
$test = (bool) $fruits[$i] == $fruits2[$i];
}
This can not work as I am using associative array. What would be the best way to go to achieve that? (This loops is going to be ran intensity so I would like to keep it as light as possible)
EDIT to give more detail on what I am trying to do:
Here is a better example of what I am trying to achieve:
$array = array ( 1,2,3,4,3,2 );
$array2 = array ( 9,6,3,4,3,2 );
$counts = array_count_values( $words );
$counts2 = array_count_values( $words2 );
Given the arrays above I need to calculate which array as the highest duplicate integers. Imagine a poker game, comparing two hands that each contain duplicate cards, how to evaluate which set of duplicate (whether double, triple or quadruple ) as the highest value.
Use array array_values ( array $input ) function and compare them.
$value1=array_values($fruits);
$value2=array_values($fruits2);
for ( $i = 0; $i < count($value1); $i++)
{
$test[] = $value1[$i] == $value2[$i] ? TRUE : FLASE;
}
Got it working this way :
$n = count($fruits);
for ( $i = 0; $i < $n; $i++)
{
$cur_vals_1 = each ($fruits);
$cur_vals_2 = each ($fruits2);
$sum1 += $cur_vals_1['key'] * $cur_vals_1['value'];
...
}
You're probably chasing the wrong solution. To find the highest duplicate in an array I'd use this (PHP 5.3+ syntax):
max(array_keys(array_filter(array_count_values($array), function ($i) { return $i >= 2; })))
Do this for both arrays and compare which result is higher. Trying to compare both against each other at the same time is too convoluted.
You don't need the ternary operator.
Also, be careful with count() as it will fail if your array is null.
They also need to be equal lengths or you'll get an error.
if( is_array($value1) && is_array($value2) && count($value1)==count($value2) ) {
for ( $i = 0; $i < count($value1); $i++)
{
$test[] = ($value1[$i] == $value2[$i]);
}
}
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.