How to loop through this array? - php

I have this array where the first two elements are integers and the third element is another array containing 2 arrays, each with one element. I can loop through the first 2 elements fine but not the third element.
I have tried using a second foreach loop and also a for loop containing a foreach loop.
$rows = array(1, 2, "qa" => array("q" => array(1,2), "b" => array(3,4)));
$f=1;
foreach($rows as $r) {
if($f == 1){
$e = $rows[0];
$f=$f+1;
}
if($f == 2){
$u = $rows[1];
}
if($r == "qa"){
$c = $value["q"];
$d = $value["b"];
}
}
echo $e;
echo $u;
print_r($c);
print_r($d);

I hope this helps:
$rows = array(1, 2, "qa" => array("q" => array(1,2), "b" => array(3,4)));
view($rows);
function view($arr) {
foreach ($arr as $value) {
if (is_array($value))
view($value);
else
echo $value;
}
}

You could use array_walk_recursive
array_walk_recursive($rows, function($v){echo $v;});
DEMO: https://3v4l.org/ITXAu

Related

Get only required arrays in php

I am trying to get only required keys for an array from another array as below.
$list = array();
$arrKeys = array("id", "name");
foreach ($_SESSION['bArray'] as $i => $m) {
if(count(array_intersect(array_keys($m), $arrKeys)) > 0) {
$list[$i] = $m;
}
}
But for the $list, it always contains $m. How can I solve this?
If you change $arrKeys to have keys (rather than values) that match those you wish to keep, you can use array_intersect_key to do what you want:
$list = array();
$arrKeys = array("id" => 0, "name" => 0);
foreach ($_SESSION['bArray'] as $i => $m) {
$intersect = array_intersect_key($m, $arrKeys);
if (count($intersect)) {
$list[$i] = $intersect;
}
}
Demo on 3v4l.org

How to recursively combine array in php

I want to combine two arrays into a dictionary.
The keys will be the distinct values of the first array, the values will be all values from the second array, at matching index positions of the key.
<?php
$a=[2,3,4,5,6,7,8,9,10];
$b=[1,1,3,2,1,2,6,8,8];
?>
array_combine($b,$a);
Expected result as
<?php
/*
Value '1' occurs at index 0, 1 and 4 in $b
Those indices map to values 2, 3 and 6 in $a
*/
$result=[1=>[2,3,6],3=>4,2=>[5,7],6=>8,8=>[9,10]];
?>
There are quite a few PHP array functions. I'm not aware of one that solves your specific problem. you might be able to use some combination of built in php array functions but it might take you a while to weed through your choices and put them together in the correct way. I would just write my own function.
Something like this:
function myCustomArrayFormatter($array1, $array2) {
$result = array();
$num_occurrences = array_count_values($array1);
foreach ($array1 AS $key => $var) {
if ($num_occurrences[$var] > 1) {
$result[$var][] = $array2[$key];
} else {
$result[$var] = $array2[$key];
}
}
return $result;
}
hope that helps.
$a=[2,3,4,5,6,7,8,9,10];
$b=[1,1,3,2,1,2,6,8,8];
$results = array();
for ($x = 0; $x < count($b); $x++) {
$index = $b[$x];
if(array_key_exists ($index, $results)){
$temp = $results[$index];
}else{
$temp = array();
}
$temp[] = $a[$x];
$results[$index] = $temp;
}
print_r($results);
Here's one way to do this:
$res = [];
foreach ($b as $b_index => $b_val) {
if (!empty($res[$b_val])) {
if (is_array($res[$b_val])) {
$res[$b_val][] = $a[$b_index];
} else {
$res[$b_val] = [$res[$b_val], $a[$b_index]];
}
} else {
$res[$b_val] = $a[$b_index];
}
}
var_dump($res);
UPDATE: another way to do this:
$val_to_index = array_combine($a, $b);
$result = [];
foreach ($val_to_index as $value => $index) {
if(empty($result[$index])){
$result[$index] = $value;
} else if(is_array($result[$index])){
$result[$index][] = $value;
} else {
$result[$index] = [$result[$index], $value];
}
}
var_dump($result);

How to return elements of an array with the highest values?

In my code I have two elements which has the same age "Joe"=>"43" and "Rob"=>"43" .
My code output is:
Joe
I want to output:
Joe and Rob
Because they has the highest value.
This is my code:
<?php
$cur = 1;
$age = array("Peter" => "35", "Ben" => "37", "Joe" => "43", "Rob" => "43");
$new_array = array();
arsort($age);
$new_array = $age;
$key = array_search(max($new_array), $new_array);
while ($cur > 0) {
echo $key;
$cur--;
}
?>
I'd change the keys and values in the array, then sort by key and return the values of the first key:
$ages = array("Peter" => "35", "Ben" => "37", "Joe" => "43", "Rob" => "43");
$new = array();
foreach ($ages as $name => $age) {
$new[$age][] = $name;
}
uksort($new, function($ka, $kb) { return $kb - $ka; }); // or just krsort($new);
$new = array_values($new)[0]; // <- to use this you have to have at least PHP 5.4
// if you have PHP < 5.4 you can simply do it in two steps:
// $new = array_values($new);
// $new = $new[0];
See it in action!
EDIT: even simpler!
$ages = array("Peter" => "35", "Ben" => "37", "Joe" => "43", "Rob" => "43");
$max = max($ages);
$new = array_keys(array_filter($ages, function ($age) use ($max) { return $age == $max; }));
Use:
$people = array("Peter" => "35", "Ben" => "37", "Joe" => "43", "Rob" => "43");
$max = max($people);
$result = array_filter($people, function($age) use ($max){ return $max == $age; });
The result is:
Array
(
[Joe] => 43
[Rob] => 43
)
Just check it manually:
$age = array("Peter" => "35", "Ben" => "37", "Joe" => "43", "Rob" => "43");
$new_array = array();
arsort($age);
$new_array = $age;
$max = max($new_array);
$results = array();
foreach ($new_array as $key => $val) {
if ($val == $max) {
$results[] = $key;
}
}
echo implode(' and ', $results);
// will output "joe and bob"
I like the answer of #matteo-tassinari and #evilive much more and wanted to propose it myself. But since the question of efficency came up, here is a solution using only one loop and therefore has a linear time complexity:
<?php
$max = ~PHP_INT_MAX;
$result = [];
foreach($age as $key => $value) {
if($value > $max) {
$result = [ $key => $value ];
$max = $value;
}
if($value == $max) {
$result[$key] = $value;
}
}
var_dump($result);
And there exists another solution, that uses bucket sort:
function bucket($ages) {
$buckets = [];
foreach($ages as $key => $value) {
$buckets[$value][] = $key;
}
return $buckets[max(array_keys($buckets))];
}
Regarding the discusson about peformance and scalability, I wrote a small benchmark script for four kinds of proposed solutions (loop, sort, filter, bucket):
<?php
function loop($ages) {
$max = 0;
$result = [];
foreach($ages as $key => $value) {
if($value > $max) {
$result = [ $key => $value ];
$max = $value;
}
if($value == $max) {
$result[$key] = $value;
}
}
return array_keys($result);
}
function filter($ages) {
$max = max($ages);
$new = array_filter($ages, function ($age) use ($max) { return $age == $max; });
return array_keys($new);
}
function bucket($ages) {
$buckets = [];
foreach($ages as $key => $value) {
$buckets[$value][] = $key;
}
return $buckets[max(array_keys($buckets))];
}
for($n = 2; $n < 10000000; $n*=2) {
$ages = [];
for($i = 0; $i < $n; $i++) {
$ages['name_'.$i] = rand(0,100);
}
$start = microtime(true);
echo $n.';';
loop($ages);
echo (microtime(true) - $start).';';
$start = microtime(true);
arsort($ages);
echo (microtime(true) - $start).';';
$start = microtime(true);
filter($ages);
echo (microtime(true) - $start).';';
bucket($ages);
echo (microtime(true) - $start).';';
echo PHP_EOL;
}
Limited Live Test
Please double-check if this is right: Using php-5.6.15 on the command line, my timings look something like this:
elements;loop;sort;filter;bucket
...
4096;0.001507;0.009868;0.01211;0.01453;
8192;0.003704;0.002483;0.02488;0.03035;
16384;0.006660;0.01010;0.05396;0.06723;
32768;0.01417;0.01271;0.09163;0.1163;
...
1048576;0.4227;0.9791;2.983;3.943;
2097152;0.8572;2.320;6.064;8.020;
4194304;1.787;4.981;11.90;16.04;
8388608;3.892;10.84;24.76;33.31;
For small number of elements, the difference between the methods is not really big, but as you can see, for the largest value the loop method is two times faster than sort, 8 times faster than filter and eleven times faster than bucket. So if your array is huge, you should use loop.
I'd do something like this
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43","Rob"=>"43");
$max = max($age); //get the highest age
foreach ($age as $key => $value) { //iterate through $age array
if ($value == $max) { //if the value is equal to max age
echo $key."<br />"; // then echo the key
}
}
You can use the array methods next and key.
With next() you will move the array pointer one position. With key() you will get the key of the element of the array pointer. So the final code will be something like this:
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43","Rob"=>"43");
arsort($age);
echo key($age);
next($age);
echo key($age);
Check it working here.
I'm wondering why no one is using built in solution:
$age = array("Peter"=>"35","Ben"=>"37","Joe"=>"43","Rob"=>"43");
$new = array_keys($age, max($age));
returns
array('Joe', 'Rob')
https://www.php.net/manual/en/function.array-keys.php says:
array_keys ( array $array , mixed $search_value [, bool $strict = FALSE ] ) : array
If a search_value is specified, then only the keys for that value are returned. Otherwise, all the keys from the array are returned.

Unsort in array

Good day.
I would be like get 3 keys from $arr where value $arN[0] will be more than other...
Code:
$ar1=array(201,281);
$ar2=array(1252760,1359724);
$ar3=array(452760,34349724);
$ar4=array(1260,134344);
$ar5=array(232750,1359724);
$ar6=array(60,1439724);
$arr[]=array(6299927 => $ar1);
$arr[]=array(1252760 => $ar2);
$arr[]=array(3432444 => $ar3);
$arr[]=array(3435543 => $ar4);
$arr[]=array(7645466 => $ar5);
$arr[]=array(4574534 => $ar6);
Next function sorting array $a descending:
function cmp($a, $b)
{
if ($a == $b) {
return 0;
}
return ($a < $b) ? 1 : -1;
}
$a = array(3, 2, 5, 6, 1);
usort($, "cmp");
foreach ($a as $key => $value) {
echo "$key: $value\n";
}
outpoot: 0:6 1:5 2:4 3:2 4:1
But how change this function for my example(for my big array)?
Tell me please how make this?
How write right?
Very confusing but I think you are looking for something like this. It will give you the index of the array whose first item is greater than the first item in the next array.
foreach($arr as $key => $array) {
if($array[0] > $arr[$key+1][0]) {
echo $key;
}
}
$dates = array();
foreach ($arr as $key => $row) {
$subkeys = array_keys($row); // Elements are one-element associative arrays
$dates[$key] = $row[$subkeys[0]][0]; // Get the element, then get its [0] sub-element
}
array_multisort($dates, SORT_DESC, $arr);
print_r($arr);
$ans_array= array();
// for shuffle array without repeat
for($q=0;$q<count($arr);$q++)
{
$n = rand(0,count($arr));
if($ans_array[$n] == NULL || $ans_array[$n] == '')
{
$ans_array[$n] = $arr[$q];
}
else
{ if($q==0) $q=0;
else $q = $q-1;
}
}

print all arrary values except first value - php

I have an array of numbers. I can print all values using for each command in php. But what I want is, I don't want to print first value (ie, array[0]) and want to print all other values.
foreach($array as $k=>$val){
if($k){echo $val;}
}
for brevity, i did only exactly what was asked. The first index has a value of 0 which is falsy, so the value won't get echoed when tested in the if condition.
$cloneArray = $array;
array_shift($cloneArray); // will remove the first element of array
foreach($cloneArray as $key => $value){
echo $key." = ".$value;
}
this will also work if your array is in format of
array('key1' => 'value1', 'key2'=> 'value2', ...)
There are dozens..thousands of simple ways to do this. I'm going to list six:
$array = array(5, 6, 7, 8, 9);
foreach ($array as $index => $elem) {
if ($index == 0) {
continue;
}
echo $elem;
}
foreach($array as $index => $elem) {
if ($index != 0) {
echo $elem;
}
}
for ($x = 1; $x < count($array); $x++) {
echo $array[$x];
}
$keep = array_shift($array);
foreach ($array as $index => $elem) {
echo $elem;
}
array_unshift($array, $keep);
foreach (array_diff($array, array($array[0])) as $elem) {
echo $elem;
}
function print_not_zero($elem, $index) {
if ($index) {
echo $elem;
}
}
array_walk($array, 'print_not_zero');
I don't want to insult you, but as a developer you should think more critically for a moment and take the time to visualize the problem. Otherwise you might waste too much time on stackoverflow.
$i = 0
foreach($array as $single)
{
if ($i > 0)
echo $single;
$i++;
}
Although, unless you're using an associative array, a for cycle would be better perhaps.
$i=array(0,1,2,3);
foreach($i as $key=>$value)
{
if($key!='0')
echo $value;
}

Categories