0

I'm semi-new to PHP and looking for a good way to match arrays. Note that I'm going to write my arrays here in python syntax because its way easier to type, but I'm working in PHP.

I have an array that is something like this: {3:4,5:2,6:2}

Then I have an array of arrays, with the inners arrays having the same basic form as the array above. I'd like to write a function that returns all arrays that match the given array, ignoring extra values.

So I want the array above to match {3:4,6:2,5:2} or {3:4,5:2,6:2,7:2}

but not {3:4,5:2} or {3:4,5:2,6:3}

I probably could get it to work, but I doubt the code would be all that great. So I'd love the opinion of better PHP developers.

Thanks

4 Answers 4

3

you want array_intersect or array_intersect_key

$a = array(1 => 11, 3 => 33, 2 => 22);
$b = array(3 => 33, 5 => 55, 2 => 22, 1 => 11);

if (array_intersect_key($a, $b) == $a)
    echo "b contains a";
Sign up to request clarification or add additional context in comments.

Comments

0

I don't think there is a pre-defined function in php that will help with this sort of thing. Just loop through all the arrays and find the ones that match your criteria.

function query( $query, $arrayOfArrays) {

  $ret = array();
  foreach( $arrayOfArrays as $array) {
    if( matches( $array, $query) ) {
      $ret[] = $array;
    }
  }
  return $ret;
}

function matches( $array, $query) {
  foreach( $query as $key => $value) {
    if( !isset( $array[$key]) || $array[$key] != $value) {
      return false;
    }
  }
  return true;
}

1 Comment

I ended up using this code, but changing the matches function to use the intersect function.
0

If you have PHP 5.3 then you can use a closure along with array_filter:

// array to test against
$test = array(
    3 => 4,
    5 => 2,
    6 => 2
);

// array of arrays you need to check
$subjects = array(
    array(3 => 4, 5 => 2, 6 => 2),
    array(3 => 4, 6 => 2, 5 => 2, 7 => 2),
    array(3 => 4, 5 => 2),
    array(3 => 4, 5 => 2, 6 => 3),
);

// make $test available within the filter function with use
$result = array_filter($subjects, function($subject) use ($test) 
{
    // making use of array_intersect_key
    // note that $subject must be the first parameter for this to work
    return array_intersect_key($subject, $test) == $test;
});

$result will contain only the matching arrays

Comments

0

Filter out any row which does not match all of the associative elements in the search array. Demo

$needle = [3 => 4, 5 => 2, 6 => 2];

$haystack = [
    [3 => 4, 5 => 2],
    [5 => 2, 3 => 4, 6 => 2],
    [3 => 4, 6 => 2, 5 => 2, 7 => 2],
    [3 => 4, 5 => 2, 6 => 3],
];

var_export(
    array_filter(
        $haystack,
        fn($hay) => !array_diff_assoc(
            $needle,
            $hay
        )
    )
);
array (
  1 => 
  array (
    5 => 2,
    3 => 4,
    6 => 2,
  ),
  2 => 
  array (
    3 => 4,
    6 => 2,
    5 => 2,
    7 => 2,
  ),
)

Comments

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.