0

I have some Problems reducing a multidimensional array into a normal one.

I have an input array like this:

Array
(
[0] => Array (
        [0] => 17
        [1] => 99
    )
[1] => Array (
        [0] => 17
        [1] => 121
    )
[2] => Array (
        [0] => 99
        [1] => 77
    )
[3] => Array (
        [0] => 45
        [1] => 51
    )
[4] => Array (
        [0] => 45
        [1] => 131
    )

So I have a multidimensional array with some overlaps in the values (eg 17,99 and 17,121) Now I want to have an output like this:

Array
(
[0] => Array (
        [0] => 17
        [1] => 99
        [2] => 121
        [3] => 77
    )
[2] => Array (
        [0] => 45
        [1] => 51
        [3] => 131
    )

I want to save, which articles are the same in my database this way. The output array shpuld still be a multidimesional array, but every number on the second level should be unique in the array.

I'm trying to solve this for more than a week now, but I dont get it to work. I know it should be easy...but anyway - I dont get it :D

This is what i got so far:

$parity_sorted = array();
    foreach($arr as $key => $a){
        if(count($parity_sorted) > 0){
        foreach($parity_sorted as $key2 => $arr_new){
            if(in_array($a[0], $arr_new) || in_array($a[1], $arr_new)){
                if(!in_array($a[0], $arr_new)){array_push($parity_sorted[$key2], $a[0]);}
                if(!in_array($a[1], $arr_new)){array_push($parity_sorted[$key2], $a[1]);}
            } else {
                array_push($parity_sorted, array($a[0],$a[1]));
            }
        }
        } else {
            array_push($parity_sorted, array($a[0],$a[1]));
        }

    }

Did you maybe already solve problem like this or is there a much easier way? Maybe I just think too complicated (It's not my first try, but this code was the last try)

Any help would be appreciated. Thanks a lot

7
  • 4
    Umm your example "reduced" array is also multidimensional. Can you explain more about how the reduction is supposed to work? Commented Nov 6, 2012 at 20:48
  • From what I can tell, this is just an array_unique() with an array_chunk(). Commented Nov 6, 2012 at 20:53
  • @durron597 oh...you are right. Had some Problems finding a good thread name in english :-/ Any Suggestions? :D Commented Nov 6, 2012 at 20:54
  • I believe it's array_intersect and not array_chcuk. He should definitely explain himself :) Commented Nov 6, 2012 at 20:55
  • The output array shpuld still be a multidimesional array, but every number on the second level should be unique in the array. I'll have a look at array_unique(), array_unique() and array_intersect(). Thanks so far. Commented Nov 6, 2012 at 20:57

5 Answers 5

1

Here is my revised code given your comment and a DEMO of it working as expected. ( http://codepad.org/CiukXctS )

<?php

$tmp = array();
foreach($array as $value)
{
    // just for claraty, let's set the variables
    $val1 = $value[0];
    $val2 = $value[1];
    $found = false;
    foreach($tmp as &$v)
    {
        // check all existing tmp for one that matches
        if(in_array($val1, $v) OR in_array($val2, $v))
        {
            // this one found a match, add and stop
            $v[] = $val1;
            $v[] = $val2;
            // set the flag
            $found = true;
            break;
        }
    }
    unset($v);

    // check if this set was found  
    if( ! $found)
    {
        // this variable is new, set both
        $tmp[] = array(
                $val1,
                $val2,
                );
    }
}

// go trough it all again to ensure uniqueness
$array = array();
foreach($tmp as $value)
{
    $array[] = array_unique($value); // this will eliminate the duplicates from $val2
}

ORIGIN ANSWER

The question is badly asked, but I'll attempt to answer what I believe the question is.

You want to gather all the pairs of arrays that have the same first value in the pair correct?

$tmp = array();
for($array as $value)
{
    // just for claraty, let's set the variables
    $val1 = $value[0];
    $val2 = $value[1];

    if(isset($tmp[$val1])) // we already found it
    {
        $tmp[$val1][] = $val2; // only set the second one
    }
    else
    {
        // this variable is new, set both
        $tmp[$val1] = array(
            $val1,
            $val2,
        );
    }
}
// go trough it all again to change the index to being 0-1-2-3-4....
$array = array();
foreach($tmp as $value)
{
    $array[] = array_unique($value); // this will eliminate the duplicates from $val2
}
Sign up to request clarification or add additional context in comments.

3 Comments

its not only the first value array(17,99) and array(99,77) should be gathered to array(17,99,77) as well. Its enough if one of the pairs is in one of the arrays. Sorry - sometimes its quite hard to explain in other than your native language :P
This helps a lot dude. Works very well. In those moments I realize, that i still have to learn a lot :) I'll take a closer look at it
I don't think this case would work: Array ( [0] => Array ( [0] => 17 [1] => 99 ) [1] => Array ( [0] => 17 [1] => 121 ) [2] => Array ( [0] => 99 [1] => 77 ) [3] => Array ( [0] => 45 [1] => 51 ) [4] => Array ( [0] => 45 [1] => 17 )
0

Here is solution for common task.

$data = array(array(17,99), array(17,121), array(99,77), array(45,51), array(45,131));
$result = array();
foreach ($data as $innner_array) {
    $intersect_array = array();
    foreach ($result as $key => $result_inner_array) {
        $intersect_array = array_intersect($innner_array, $result_inner_array);
    }
    if (empty($intersect_array)) {
        $result[] = $innner_array;
    } else {
        $result[$key] = array_unique(array_merge($innner_array,     $result_inner_array));
    }

}
var_dump($result);

1 Comment

didn't work the first time, but i'll take a closer look at it.
0

Try:

$arr = array(array(17,99), 
            array(17,121),
            array(99,77),
            array(45, 51),
            array(45, 131)
      );

 foreach($arr as $v)
  foreach($v as $m)
    $new_arr[] = $m;

  $array = array_chunk(array_unique($new_arr), 4);
  var_dump($array);

Demo It uses array_unique and array_chunk.

Output:

 array(2) { [0]=>array(4) { [0]=> int(17) [1]=>int(99)
            [2]=>int(121) [3]=> int(77) }
            [1]=> array(3) { [0]=> int(45) [1]=>int(51)
            [2]=>int(131) }
          }

5 Comments

This won't actually work. It works in the given case but only because it is a special case. If you change the order of $arr it gives the wrong answer. codepad.org/W5YEWYnf
Hey, unfortunatly this will only work for this example if im right. Because the size of the reduced arrays is variable and not always 4.If the input would be in a different order this wont work anymore. But thank you
It gives the right result in this case, but it's not the right answer to the question. The idea is not to chuck into groups of 4, but to group arrays with common values.
@KddC: If the size of the reduced arrays is variable, then what determines that? Can you show the code for that? Everything apart from grouping, seems to work, if I understand it correctly that you want unique values.
Grouping should work as well. But i think this is clear from examples like array(17,99) and array(99,77) to array(17,77,99).
0

I think I get your problem. Let me have a crack at it.

$firstElems = array();
$secondElems = array();
foreach ( $arr as $v ) {
    $firstElems[ $v[0] ] = array( $v[0] );
}
foreach ( $arr as $v ) {
    $secondElems[ $v[1] ] = $v[0];
}

foreach ( $arr as $v ) {
    if ( isset( $secondElems[ $v[0] ] ) ) {
        array_push( $firstElems[ $secondElems[ $v[0] ] ], $v[1] );
    }
    else {
        array_push( $firstElems[ $v[0] ], $v[1] );
    }
}

foreach ( $firstElems as $k => $v ) {
    if ( isset( $secondElems[ $k ] ) ) {
        unset( $firstElems[ $k ] );
    }
}

Output:

Array
(
    [17] => Array
        (
            [0] => 17
            [1] => 99
            [2] => 121
            [3] => 77
        )

    [45] => Array
        (
            [0] => 45
            [1] => 51
            [2] => 131
        )

)

Comments

0

(Code examples: http://codepad.org/rJNNq5Vd)

I truly believe I understand you and if this is the case here is what you're looking for:

function arrangeArray($array) {
    $newArray = array(array_shift($array));

    for ($x = 0; $x < count($newArray); $x++) {
        if (!is_array($newArray[$x])) {
            unset($newArray[$x]);
            return $newArray;
        }
        for ($i = 0; $i < count($newArray[$x]); $i++) {
            foreach ($array as $key => $inArray) {
                if (in_array($newArray[$x][$i], $inArray)) {
                    $newArray[$x] = array_unique(array_merge($newArray[$x], $inArray));
                    unset($array[$key]);
                }
            }
        }
        $newArray[] = array_shift($array);
    }
}

Which will return:

array(2) {
  [0]=>
  array(4) {
    [0]=>
    int(17)
    [1]=>
    int(99)
    [2]=>
    int(121)
    [4]=>
    int(77)
  }
  [1]=>
  array(3) {
    [0]=>
    int(45)
    [1]=>
    int(51)
    [3]=>
    int(131)
  }
}

For:

var_dump(arrangeArray(array(
    array(17,99),
    array(17,121),
    array(99,77),
    array(45, 51),
    array(45, 131),
)));

And:

array(1) {
  [0]=>
  array(6) {
    [0]=>
    int(17)
    [1]=>
    int(99)
    [2]=>
    int(121)
    [3]=>
    int(45)
    [4]=>
    int(77)
    [6]=>
    int(51)
  }
}

For:

var_dump(arrangeArray(array(
    array(17,99),
    array(17,121),
    array(99,77),
    array(45, 51),
    array(45, 17),
)));

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.