Loop an array of array - php

in PHP, how can i loop an array of array without know if is or not an array?
Better with an example:
Array
(
[0] => Array
(
[0] => big
[1] => small
)
[1] => Array
(
[0] => big
[1] => tiny
)
[2] => Array
(
[0] => a
[1] => b
[2] => c
[3] => d
[4] => e
[5] => f
)
[3] => row
[4] => cols
[5] => blablabla
[6] => Array
(
[0] => asd
[1] => qwe
)
}
any idea? thanks.

Which approach to choose depends on what you want to do with the data.
array_walk_recursive [docs] lets you traverse an array of arrays recursively.

You can use is_array to check if that element is an array, if it is, loop over it recursively.

You can use is_array to check if something is an array, and/or you can use is_object to check if it can be used within foreach:
foreach ($arr as $val)
{
if (is_array($val) || is_object($val))
{
foreach ($val as $subval)
{
echo $subval;
}
}
else
{
echo $val;
}
}
Another alternative is to use a RecursiveIteratorIterator:
$it = new RecursiveIteratorIterator(
new RecursiveArrayIterator($arr),
RecursiveIteratorIterator::SELF_FIRST);
foreach($it as $value)
{
# ... (each value)
}
The recursive iterator works for multiple levels in depth.

foreach( $array as $value ) {
if( is_array( $value ) ) {
foreach( $value as $innerValue ) {
// do something
}
}
}
That would work if you know it will be a maximum of 2 levels of nested array. If you don't know how many levels of nesting then you will need to use recursion. Or you can use a function such as array_walk_recursive

$big_array = array(...);
function loopy($array)
{
foreach($array as $element)
{
if(is_array($element))
{
// Keep looping -- IS AN ARRAY--
loopy($element);
}
else
{
// Do something for this element --NOT AN ARRAY--
}
}
}
loopy();

Related

How to tell if array contains another array

Well this has been a headache.
I have two arrays;
$array_1 = Array
(
[0] => Array
(
[id] => 1
[name] => 'john'
[age] => 30
)
[1] => Array
(
[id] => 2
[name] => 'Amma'
[age] => 28
)
[2] => Array
(
[id] => 3
[name] => 'Francis'
[age] => 29
)
)
And another array
array_2 = = Array
(
[0] => Array
(
[id] => 2
[name] => 'Amma'
)
)
How can I tell that the id and name of $array_2 are the same as the id and name of $array_1[1] and return $array_1[1]['age']?
Thanks
foreach($array_1 as $id=>$arr)
{
if($arr["id"]==$array_2[0]["id"] AND $arr["name"]==$array_2[0]["name"])
{
//Do your stuff here
}
}
Well you can do it in a straightforward loop. I am going to write a function that takes the FIRST element in $array_2 that matches something in $array_1 and returns the 'age':
function getField($array_1, $array_2, $field)
{
foreach ($array_2 as $a2) {
foreach ($array_1 as $a1) {
$match = true;
foreach ($a2 as $k => $v) {
if (!isset($a1[$k]) || $a1[$k] != $a2[$k]) {
$match = false;
break;
}
}
if ($match) {
return $a1[$field];
}
}
}
return null;
}
Use array_diff().
In my opinion, using array_diff() is a more generic solution than simply comparing the specific keys.
Array_diff() returns a new array that represents all entries that exists in the first array and DO NOT exist in the second array.
Since your first array contains 3 keys and the seconds array contains 2 keys, when there's 2 matches, array_diff() will return an array containing the extra key (age).
foreach ($array_1 as $arr) {
if (count(array_diff($arr, $array_2[1])) === 1) {//meaning 2 out of 3 were a match
echo $arr['age'];//prints the age
}
}
Hope this helps!
I assume you want to find the age of somebody that has a known id and name.
This will work :
foreach ($array_1 as $val){
if($val['id']==$array_2[0]['id'] && $val['name']==$array_1[0]['name']){
$age = $val['age'];
}
}
echo $age;
Try looking into this.
http://www.w3schools.com/php/func_array_diff.asp
And
comparing two arrays in php
-Best

most common values in a multidemensional array

My question is maybe repetitive but I really find it hard. (I have read related topics)
This is the array :
Array
(
[0] => Array
(
[legend] => 38440
)
[1] => Array
(
[bestw] => 9765
)
[2] => Array
(
[fiuna] => 38779
)
[3] => Array
(
[adam] => 39011
)
[4] => Array
(
[adam] => 39011
)
[5] => Array
(
[adam] => 39011
)
)
I have tried many ways to handle this array and find out the most common value. The result I expect is "adam"
$countwin = array_count_values($winnernames);
$maxwin = max($countwin);
$mostwinner = array_keys($countswin, $maxwin);
EDIT : My array is like this array("A"=>"1" , "B"=>"2" , "A"=>"1") it should return A is the most common
How about iterating your array and counting the values you've got?
$occurences = array();
foreach ($data as $row) {
foreach ($row as $key => $score) {
if (empty($occurences[$key])) {
$occurences[$key] = 1;
} else {
$occurences[$key]++;
}
}
}
and then sorting that
arsort($occurences);
and grabbing the first element of the sorted array
$t = array_keys($occurences);
$winner = array_shift($occurences);
You may try this code. A brute force method indeed. But a quick search made me to find this an useful one:
function findDuplicates($data,$dupval) {
$nb= 0;
foreach($data as $key => $val)
if ($val==$dupval) $nb++;
return $nb;
}
EDIT : Sorry, I misinterpreted your question! But it might be the first hint of finding the one with maximum counter.

PHP -> Pick value from two-dimensional array based on key

I need to pick a value based on a specific key from an two-dimensional array, how would I do that?
I only know the key of the second level in the array in my code, and not in which array key it sits in level 1...
example:
Array
(
[0] => Array
(
[1] => http://stackoverflow.com/
)
[1] => Array
(
[0] => http://www.google.com
)
[2] => Array
(
[20567] => http://www.yahoo.com
)
)
Now I would like to pick the value of the key 20567 dynamically, I don't know where it sits in level 1, could be 0, 1,2 or any other key.
I hope I explained that well enough :)
You could use a RecursiveArrayIterator and RecursiveIteratorIterator:
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
foreach ($iterator as $key => $value) {
if ($key == 20567) {
var_dump($value);
break;
}
}
Example in a function:
function valueForKey($array, $key) {
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
foreach ($iterator as $arrayKey => $arrayValue) {
if ($arrayKey == $key) {
return $arrayValue
}
}
return null;
}
Another option is: (should work)
function getURLbyRedirects($redirectNumber , $array)
{
foreach($array as $lvl => $elems)
{
if(array_key_exists($redirectNumber , $elems))
return $elems[$redirectNumber];
}
return false;
}
By the way , consider using a different structre for this array, something like this:
Array (
[0] => Array
(
[url] => http://stackoverflow.com/
[redirects] => 2067
)

How to go a level up in an array?

I want would like to get the parent node of the array below, but I don't find a way to easily do this.
Normally for getting the id, I would do this in PHP:
echo $output['posts']['11']['id'];
But how can I get to the parent node "11" when I get the value of "id" passed from a $_GET/$_POST/$_REQUEST? (ie. $output['posts']['11'][$_GET[id]])
Array
(
[posts] => Array
(
[11] => Array
(
[id] => 482
[time] => 2011-10-03 11:26:36
[subject] => Test
[body] =>
[page] => Array
(
[id] => 472
[title] => News
)
[picture] => Array
(
[0] => link/32/8/482/0/picture_2.jpg
[1] => link/32/8/482/1/picture_2.jpg
[2] => link/32/8/482/2/picture_2.jpg
[3] => link/32/8/482/3/picture_2.jpg
)
)
)
)
$parent = null;
foreach ($array['posts'] as $key => $node) {
if ($node['id'] == $_GET['id']) {
echo "found node at key $key";
$parent = $node;
break;
}
}
if (!$parent) {
echo 'no such id';
}
Or possibly:
$parent = current(array_filter($array['posts'], function ($i) { return $i['id'] == $_GET['id']; }))
How this should work exactly depends on your array structure though. If you have nested arrays you may need a function that does something like the above recursively.
array_keys($output['posts']);
will give you all keys within the posts array, see http://php.net/manual/en/function.array-keys.php
you could try with something like:
foreach ($posts as $post){
foreach( $items as $item){
if ( $item['id'] == [$_GET[id] ){
// here, the $post is referring the parent of current item
}
}
}
I don't think it is possible while an array of array is not a DOM or any tree structure. In an array you can store any reference. but you can not naturally refer to an array containing a reference.
Check rolfs example for array_filter at php manual http://www.php.net/manual/en/function.array-filter.php#100813
So you could do it like this
$filtered = array_filter($output, function ($element) use ($_GET["id"]) { return ($element["id"] == $_GET["id"]); } );
$parent = array_pop($filtered);

convert sub-arrays with only one value to a string

I have a multidimensional array, the sub-arrays consist of further values, I would like for all sub-arrays that only have one value to be converted into a string. How can I successfully scan through a multidimensional array to get the result?
Below is a small section of the array as it is now.
[1] => Array
(
[name] => Array
(
[0] => Person's name
)
[organisation] => Array
(
[0] => This is their organisation
[1] => aka something else
)
[address] => Array
(
[0] => The street name
[1] => The town name
)
[e-mail] => Array
(
[0] => test#this.site.com
)
)
and here is how I would like it to end up
[1] => Array
(
[name] => Person's name
[organisation] => Array
(
[0] => This is their organisation
[1] => aka something else
)
[address] => Array
(
[0] => The street name
[1] => The town name
)
[e-mail] => test#this.site.com
)
This should do the trick.
function array2string(&$v){
if(is_array($v) && count($v)==1){
$v = $v[0];
}
}
array_walk($array, 'array2string');
Or as a one-liner, since I'm nuts.
array_walk($array, create_function('&$v', 'if(is_array($v) && count($v)==1){$v = $v[0];}'));
EDIT: It looks like that array is an element in a bigger array. You need to put this function inside of a foreach loop.
function array2string(&$v){
if(is_array($v) && count($v)==1){
$v = $v[0];
}
}
foreach($array as &$val){
array_walk($val, 'array2string');
}
Or using my crazy create_function one-liner.
foreach($array as &$val){
array_walk($val, create_function('&$v', 'if(is_array($v) && count($v)==1){$v = $v[0];}'));
}
This should work no matter how deep the array is.
Put this function in your code:
function array2string(&$v){
if(is_array($v)){
if(count($v, COUNT_RECURSIVE) == 1){
$v = $v[0];
return;
}
array_walk($v, 'array2string');
}
}
Then do this:
array_walk($array, 'array2string');
This PHP 5.3 code uses a closure. You can use a named function, too, if you want. It specifically checks for strings, and calls itself for nested arrays.
<?php
array_walk($array, $walker = function (&$value, $key) use (&$walker) {
if (is_array($value)) {
if (count($value) === 1 && is_string($value[0])) {
$value = $value[0];
} else {
array_walk($value, $walker);
}
}
});

Categories