Viewed   61 times

I am having trouble figuring out a way to simply parse a string input and find the correct location within a multidimensional array.

I am hoping for one or two lines to do this, as the solutions I have seen rely on long (10-20 line) loops.

Given the following code (note that the nesting could, in theory, be of any arbitrary depth):

function get($string)
{
    $vars = array(
        'one' => array(
            'one-one' => "hello",
            'one-two' => "goodbye"
        ),
        'two' => array(
            'two-one' => "foo",
            'two-two' => "bar"
        )
    );

    return $vars[$string]; //this syntax isn't required, just here to give an idea
}

get("two['two-two']");  //desired output: "bar".  Actual output: null

Is there a simple use of built-in functions or something else easy that would recreate my desired output?

 Answers

2

Considering $vars being your variables you would like to get one['one-one'] or two['two-two']['more'] from (Demo):

$vars = function($str) use ($vars)
{
    $c = function($v, $w) {return $w ? $v[$w] : $v;};
    return array_reduce(preg_split('~['|']~', $str), $c, $vars);
};
echo $vars("one['one-one']"); # hello
echo $vars("two['two-two']['more']"); # tea-time!

This is lexing the string into key tokens and then traverse the $vars array on the keyed values while the $vars array has been turned into a function.


Older Stuff:

Overload the array with a function that just eval's:

$vars = array(
    'one' => array(
        'one-one' => "hello",
        'one-two' => "goodbye"
    ),
    'two' => array(
        'two-one' => "foo",
        'two-two' => "bar"
    )
);

$vars = function($str) use ($vars)
{
    return eval('return $vars'.$str.';');
};

echo $vars("['one']['one-two']"); # goodbye

If you're not a fan of eval, change the implementation:

$vars = function($str) use ($vars)
{
    $r = preg_match_all('~['([a-z-]+)']~', $str, $keys);
    $var = $vars;
    foreach($keys[1] as $key)
        $var = $var[$key];
    return $var;
};
echo $vars("['one']['one-two']"); # goodbye
Monday, November 7, 2022
1

To add to Rikesh's answer:

<?php
$aryMain = array(array('hello','bye'), array('',''),array('','')); 
$aryMain = array_filter(array_map('array_filter', $aryMain));
print_r($aryMain);

?>

Sticking his code into another array_filter will get rid of the entire arrays themselves.

Array
(
    [0] => Array
        (
            [0] => hello
            [1] => bye
        )

)

Compared to:

$aryMain = array_map('array_filter', $aryMain);

Array
(
    [0] => Array
        (
            [0] => hello
            [1] => bye
        )

    [1] => Array
        (
        )

    [2] => Array
        (
        )

)
Monday, October 31, 2022
 
5

i recommend you read some articles about multidim arrays, anyway your needs could be done with following code:

foreach($multi as $key => $value) {
    echo "<br/>Main Array Value ".$key."<br/>";
    for($i = 0; $i < sizeof($value); $i++) {
        echo "sub Value ".$value[$i]." count ".sizeof($value) ;
    }
} 

PS: you don't need $data array

Monday, November 7, 2022
1

To check multi-deminsions try something like this:

$pageWithNoChildren = array_map('unserialize',
    array_diff(array_map('serialize', $pageids), array_map('serialize', $parentpage)));
  • array_map() runs each sub-array of the main arrays through serialize() which converts each sub-array into a string representation of that sub-array
    • the main arrays now have values that are not arrays but string representations of the sub-arrays
  • array_diff() now has a one-dimensional array for each of the arrays to compare
  • after the difference is returned array_map() runs the array result (differences) through unserialize() to turn the string representations back into sub-arrays

Q.E.D.

Wednesday, August 3, 2022
 
1

I would suggest to flatten each array first:

foreach ($csv as $file) {
    $result = [];
    array_walk_recursive($file, function($item) use (&$result) {
        $result[] = $item;
    });
    fputcsv($output, $result);
}

In each iteration it would create an array like this:

[1111, 'Alcatel One Touch Idol 2', 'alcatel-one-touch-idol-2', 54, 42, ...]
Friday, November 4, 2022
 
clawish
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :