0

on http://php.net/manual/en/function.in-array.php - if you scroll down it gives a function to determine if a string is inside of a query in a multidimensional array. "If you found yourself in need of a multidimensional array in_array like function you can use the one below. Works in a fair amount of time"

Here's original code(working):

function in_multiarray($elem, $array)
{
    $top = sizeof($array) - 1;
    $bottom = 0;
    while($bottom <= $top)
    {
        if($array[$bottom] == $elem)
            return true;
        else
            if(is_array($array[$bottom]))
                if(in_multiarray($elem, ($array[$bottom])))
                    return true;

        $bottom++;
    }       
    return false;
}

What I'm trying to do is instead of returning 'true' or 'false' - i'd like to return the ROW #. So my initial thought was to simply replace 'return true' with 'return $bottom; however it isn't returning the record number.

Modified Function (not working);

   function in_multiarray($elem, $array)
    {
        $top = sizeof($array) - 1;
        $bottom = 0;
        while($bottom <= $top)
        {
            if($array[$bottom] == $elem)
                return $bottom;
            else
                if(is_array($array[$bottom]))
                    if(in_multiarray($elem, ($array[$bottom])))
                        return $bottom;

            $bottom++;
        }       
        return false;
    }

Does anyone have an idea how to modify this function to return the ROW number that contains the match?

Here's a sample of the array...

$sample = array
    array ("oldpage1.php","newpage1.php"),
    array ("oldpage2.php","newpage2.php"),
    array ("oldpage3.php","newpage3.php"),
    array ("oldpage4.php","newpage4.php"),
    array ("oldpage5.php","newpage5.php")
etc.
); 
$row = in_multiarray($input, $sample);

Therefore if we know the row # we can fetch the new page with a simple $newpage=$sample[$row][1]

Thanks!

4
  • what exactly are ryou trying to do with $sample ? Commented Sep 3, 2016 at 1:01
  • If $input='oldpage5.php' and you run it through the function - we extract the $row and from that $newpage=$sample[$row][1]; would contain the value 'newpage5.php'; Does that make sense? Commented Sep 3, 2016 at 1:13
  • i dont know what $row is suppose to be Commented Sep 3, 2016 at 1:15
  • $row would have the value '4' if $input='oldpage5.php' Commented Sep 3, 2016 at 1:22

2 Answers 2

1

It's worth noting that a function like in_array is intended to tell you whether or not a value exists inside of an array. What you're looking for seems to be a lot closer to something like array_search, which is designed to actually provide you with the key that points to a given value in the array.

However, because you're using a multi-dimensional array what you're actually looking for is the key that points to the array that contains the value. Hence we can divide and conquer this problem with two simple steps.

  1. Map
  2. Filter

The first step is to map a function in_array to every element in the first array (which is just another array). This will tell us which elements of the primary array contain an array that contains the value we're searching for.

$result = array_map(function($arr) use($search) {
    return in_array($search, $arr, true);
}, $arr, [$searchValue]);

The second step is to then return the keys to those arrays (i.e. filter the result).

$keys = array_keys(array_filter($result));

Now you have all the keys of any matching items. If you want to apply as just one custom filter that specifies exactly where in the subarray to look, you could also do it like this.

$search = "oldpage2.php";
$sample = [
    ["oldpage1.php","newpage1.php"],
    ["oldpage2.php","newpage2.php"],
    ["oldpage3.php","newpage3.php"],
    ["oldpage4.php","newpage4.php"],
    ["oldpage5.php","newpage5.php"],
];

$keys = array_keys(array_filter($sample, function($arr) use($search) {
    return $arr[0] === $search;
}));

var_dump($keys);

And you get...

array(1) {
  [0]=>
  int(1)
}

So now you know that "oldpage2.php" is in row 1 in $sample[1][0] which means you can do this to get the results out of the array.

foreach($keys as $key) {
    echo "{$sample[$key][0]} maps to {$sample[$key][1]}\n";
}

Giving you

oldpage2.php maps to newpage2.php

If you want to return only the first result you could do that as well with a function like this using similar approach.

function getFirstMatch($search, Array $arr) {
    foreach($arr as $key => $value) {
        if ($value[0] === $search) {
            return $value[1];
        }
    }
}

echo getFirstMatch("oldpage4.php", $sample); // newpage4.php

The Better Alternative

Of course, the better approach is to actually use the oldpage names as the actual keys of the array rather than do this expensive search through the array, because array lookup by key in PHP is just an O(1) operation, whereas this needle/haystack approach is O(N).

So we turn your $samples array into something like this and the search no longer requires any functions...

$samples = [
    "oldpage1.php" => "newpage1.php",
    "oldpage2.php" => "newpage2.php",
    "oldpage3.php" => "newpage3.php",
    "oldpage4.php" => "newpage4.php",
    "oldpage5.php" => "newpage5.php",
];

Now you can just do something like $newpage = $samples[$search] and you get exactly what you're looking for. So echo $samples["oldpage2.php"] gives you "newpage2.php" directly without the intermediary step of searching through each array.

Sign up to request clarification or add additional context in comments.

3 Comments

Excellent - that script works perfectly. I'd give it two ups but my reputation won't let me perhaps someone else can up this!
I like the better alternative. Its important to note that in this particular simple example => does work - perhaps in more complex arrays it will make sense to search through the array for the given variable. Learned a lot from this exercise. Thank you again.
@Viktor Sure, no problem. If you think it's the correct answer to your question you should select it as the accepted answer so that others can find it more easily if they have the same/similar question.
1

You can use the following code to get the full path to the value:

function in_multiarray($elem, $array, &$result)
{
    $top = sizeof($array) - 1;
    $bottom = 0;
    while($bottom <= $top)
    {
        if($array[$bottom] == $elem) {
            array_unshift($result, $bottom);
            return true;
        }
        else {
            if(is_array($array[$bottom])) {
                if(in_multiarray($elem, $array[$bottom], $result)) {
                    array_unshift($result, $bottom);
                    return true;
                }
            }
        }

        $bottom++;
    }
    array_shift($result);
    return false;
}

$sample = array(
    array ("oldpage1.php","newpage1.php"),
    array ("oldpage2.php","newpage2.php"),
    array ("oldpage3.php","newpage3.php"),
    array ("oldpage4.php","newpage4.php"),
    array ("oldpage5.php","newpage5.php")
);
$input = "newpage5.php";
$result = [];
in_multiarray($input, $sample, $result);

print_r($result);

Path is stored in $result;

2 Comments

Would that work if $input="oldpage5.php"? What would be $output= to produce 'newpage5.php' as the result?
You can run and see the result. However, $result will contain values 4,0 for oldpage5.php and 4,1 for newpage5.php.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.