1

I have a multidimensional array which outputs data as such (this gets filled with a foreach looping over specific items):

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

[3] => Array
    (
        [0] => 0
        [1] => 1
        [2] => 2
    )

[9] => Array
    (
        [0] => 2
    )
)

The first keys are id's of specific items, the keys on the second level are of no meaning/importance, the values however are.

As you can see in this example, the value 0 exists both in 1 and 3, and the value 2 existst in both 3 and 9 and only 1 is unique. What I'd like to achieve here is to check if any value exists within multiple items (as is here the case) and have some way of keeping track where certain values are duplicated.

How would I go about doing this? I've tried implementing multiple solutions, including the ones found here, but whatever I try, it doesn't quite seem to work the way I'd like it to.

Many thanks to whoever can help me out or point me in the right direction.

2
  • ...have some way of keeping track where certain values are duplicated... If count(array_unique(array)) < count(array) then you have/had duplicates Commented Oct 16, 2017 at 12:29
  • In what way do you want to keep track of this? Commented Oct 16, 2017 at 12:32

3 Answers 3

1

You can do this to detect if you have duplicates

$mergedValues = [];
foreach ($outerArray as $id => $innerArray) {
  $mergedValues = array_merge($mergedValues, $innerArray);
}
$uniqueValues = array_unique($mergedValues);
if (sizeof($uniqueValues) != sizeof($mergedValues)) {
  echo 'You have duplicates!', PHP_EOL;
  echo 'These are duplicates: ', implode(', ', array_unique(array_diff_assoc($mergedValues, $uniqueValues))), PHP_EOL;
}
Sign up to request clarification or add additional context in comments.

Comments

0

I like Aron Cederholm's answer, but another option you could go for you that might provide you with plenty of information is to make a kind of reverse associative array, where the values become keys and vice versa. Here's what I mean (based on Aron's initial loop):

$valueMap = [];
foreach ($outerArray as $id => $innerArray) {
    foreach ($innerArray as $value) {
        if (!isset($valueMap[$value])) $valueMap[$value] = [$id];
        else $valueMap[$value][] = $id;
    }
}

This has the benefit of giving you and array indexed by value, and for each value you can see which indices of the original array contain that value, if that makes sense. You can then check how many items contain the value you're looking for with

count($valueMap[$value])

And the item at $valueMap[$value] gives you an array of indices where those values can be found, which answers your "keep track of values" problem, right?

The downside is you've now doubled the amount of memory being used.

1 Comment

Your nested loop can be more refined: 3v4l.org/vLMv1
0

What you're looking for is in fact array_intersect and pass the array values as parameters.

Using php from 5.6 you can pass the array using variadic functions.

array_intersect(...array_values($array));

This will show you the values that are repeated all over the array.

And in the end to get the unique repeated values over the single element against the others:

$repeated = [];
foreach (array_values($array) as $analyzed_part) {
  array_map(function ($array_piece) use ($analyzed_part, &$repeated) {
    // Skip the current
    if ($analyzed_part != $array_piece) {
      $repeated[] = array_intersect($analyzed_part, $array_piece);
    }
  }, $array);
}

// Here you have all the repetitions between one element and the other
var_dump($repeated);

// Get the unique values
$unique_repeated = array_unique(array_merge(...$repeated));
var_dump($unique_repeated);

3 Comments

Your link to eval.in is wrong has a server error.
thank you @JuanAntonio for pointing it out, eval.in was closed about a year ago. I'll remove the link for the moment, if you know any good alternative please let me know
I recommend 3v4l.org for pure php demos. If you ever need to combine mysql with php, then I recommend phpize.online.

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.