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.

Nico V
  • 107
  • 1
  • 9
  • _...have some way of keeping track where certain values are duplicated..._ If count(array_unique(array)) < count(array) then you have/had duplicates – B001ᛦ Oct 16 '17 at 12:29
  • In what way do you want to keep track of this? – Xyz Oct 16 '17 at 12:32

3 Answers3

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;
}
Xyz
  • 5,955
  • 5
  • 40
  • 58
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.

Michael Beeson
  • 2,840
  • 2
  • 17
  • 25
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);
phaberest
  • 3,140
  • 3
  • 32
  • 40
  • 1
    Your link to [eval.in](https://eval.in/880808) is wrong has a server error. – Juan Antonio Oct 21 '19 at 06:34
  • 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 – phaberest Oct 22 '19 at 10:59
  • 1
    I recommend 3v4l.org for pure php demos. If you ever need to combine mysql with php, then I recommend phpize.online. – mickmackusa Sep 23 '22 at 12:29