0

For a project i found out i have to start using array intersect. http://php.net/manual/en/function.array-intersect.php

There i found this code which explains what the function does:

<?php
$array1 = array("a" => "green", "red", "blue");
$array2 = array("b" => "green", "yellow", "red");
$result = array_intersect($array1, $array2);
print_r($result);
?>

The output is what confuses me.

(
    [a] => green
    [0] => red
)

What do a and 0 mean in this case?

Shouldn't it be 0 1 why does it start with a and then goes to 0.

5
  • You already link to the answer of your question: "array_intersect() returns an array containing all the values of array1 that are present in all the arguments. Note that keys are preserved." Commented Dec 9, 2016 at 14:39
  • What is confusing you is the fact that those are not "arrays" - they're dictionaries. $array1 is [ a => green, 0 => red, 1 => blue ], has two numeric automatic keys and one text key. Use of array_intersect in this scenario is possible, but... IMHO, to be carefully avoided. Commented Dec 9, 2016 at 14:41
  • The output is, all of the values in $array1 that are present in $array2. Both "green" and "red" are found, so those keys from $array1 are preserved and the other values discarded. Commented Dec 9, 2016 at 14:43
  • To extend the clarification, the reason why you see "a" is because it comes from the first array passed to array_intersect, if you change the order array_intersect($array2, $array1) ...you will see Array ( [b] => green [1] => red ) instead Commented Dec 9, 2016 at 14:44
  • if you don't keep the key, use array_values() Commented Dec 9, 2016 at 14:44

3 Answers 3

3
$array1 = array("a" => "green", "red", "blue");
$array2 = array("b" => "green", "yellow", "red");
$result = array_intersect($array1, $array2);

First of all we must write those dictionaries as they really are; the form above is "condensed", with implicit numeric keys.

$array1 is a: green, 0: red, 1: blue
$array2 is b: green, 0: yellow, 1: red

Now array_intersect checks what values are common. They are green, and red. The corresponding items from array1 are taken:

a: green
0: red

and so you have two keys, 'a' and 0, mapped to green and red respectively.

At this point I'll add that mixing numeric and non-numeric keys is a recipe for disaster, unless you're incredibly careful about what you're doing; lots of PHP functions will not preserve keys and renumber the values converting dictionaries to arrays.

And as you have seen, it's not immediate to tell an array from a dictionary. To add to the risk, JSON encoding is completely different for the two, so a tiny change in a structure might make a Web service conversation to abruptly collapse.

JSON

This is my favourite parlor trick.

$arr = array( 'Hello', 'World' );

This JSON-encodes, as you would expect, to:

[ 'Hello', 'World' ]

Let's say I delete the last element and re-JSON:

[ 'Hello' ]

But let's say I delete an element that is not the last. What does PHP do? It removes the element and the key, but does not renumber the array. The array has now a hole. And arrays don't have holes -- dictionaries do.

So this is now a dictionary. And in JSON it suddenly becomes:

{ "1": "World" }

Which means that this example code is subtly bugged:

$arr = functionReturningArrayOfElements();

if (-1 != $killThisElement) {
    unset($arr[$killThisElement]);
}

header('Content-Type: application/json');
die(json_encode($arr));

When $killThisElement is the very last entry ($count($arr)-1), then the JSON will be encoded as an array. Otherwise, it will be encoded as a dictionary.

Before returning, I need to be sure of what I return:

$arr = array_values($arr); // This renumbers the keys, forcing it to always be an array

or

$arr['count'] = count($arr);
// This adds a non-numeric key, forcing $arr to always be a dictionary.
// The extra key is called 'count' just so it makes sense, but it is also
// a BAD IDEA, since it encourages to loop through the object instead of
// using the proper Javascript Object methods. A better choice from this
// point of view would be
$arr['comment'] = 'This is a dictionary.';
Sign up to request clarification or add additional context in comments.

2 Comments

Also helpful to know since I will be using this with json encoding
I've added some JSON considerations that you might find useful.
1
  • The array_intersect() function compares the values of two (or more) arrays, and returns the matches.

  • This function compares the values of two or more arrays, and return an array that contains the entries from array1 that are present in array2, array3, etc.

So in your case, the array has elements with and without keys, so if we compare arrays, we find that $array2 has green and red elements which are present in $array1, so if you print the array using print_r(), it will out put the array with custom & preserved keys (preserved in case of no key is assigned).

See more about array_intersect()

So if you try to print $array1, it would be like:

array:3 [
  "b" => "green"
  0 => "yellow"
  1 => "red"
]

Hope this helps!

Comments

0

For representation $array1 is built like this.

$array1 = array("a" => "green", 0 => "red", 1 => "blue");

So the fact that array_intersect maintains keys both these key:value pairs with sustain

"a" => "green", 0 => "red"

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.