2016-03-07 3 views
0

у меня есть массив как этотОбъединить массивы, которые имеют одинаковое значение

$arr=[["a","b"],["b","c"],["d","e"],["f","c"]]; 

если суб массивы разделяют такое же значение, они должны быть объединены в один массив

ожидается выход:

$arr=[["a","b","c","f"],["d","e"]]; 

I `m пытается избежать выполнения foreach внутри foreach для решения этого.

+0

A) Покажите нам какой-нибудь код. B) Является ли это ключом или ключом => значение пары? –

+1

Попробуйте рекурсию вместо итерации. Рассмотрим входной массив, например '$ arr = [[" a "," b "], [" d "," e "], [" f "," g "], [" b "," c "], [ "d", "c"]]; ' –

+0

Ваш ожидаемый результат не имеет смысла? –

ответ

0

Это решение, которое я получаю сейчас.

$arr=[["a","b","c","f"],["d","e"]]; 
    $sortedArray = sortFunction($arr,0,array()); 

function sortFunction($old,$index,$new) { 
    if ($index == sizeof($old)) return $new; 

    for ($i = 0; $i<sizeof($new); $i++) { 
     if (count(array_intersect($new[$i],$old[$index]))) { 
      $new[$i] = array_unique(array_merge($old[$index],$new[$i]), SORT_REGULAR); 
      return sortFunction($old,$index + 1,$new); 
     } 
    } 

    $new[] = $old[$index]; 
    return sortFunction($old,$index + 1,$new); 
} 
0

Следующий алгоритм должен делать то, что вы хотите. Он просто проверяет каждый пункт и проверяет, если он уже существует во вновь созданном массиве, и если он делает это добавляет к этому элементу вместо нового:

<?php 

$arr=[["a","b"],["b","c"],["d","e"],["f","c"]]; 

$newArr = []; 

foreach ($arr as $items) { 
    $newKey = null; 

    foreach ($items as $item) { 
     foreach ($newArr as $newItemsKey => $newItems) { 
      if (in_array($item, $newItems)) { 
       $newKey = $newItemsKey; 

       break 2; 
      } 
     } 
    } 

    if ($newKey !== null) { 
     $newArr[$newKey] = array_merge($newArr[$newKey], $items); 
    } else { 
     $newArr[] = $items; 
    } 
} 

$newArr = array_map('array_unique', $newArr); 

print_r($newArr); 

Выходной:

Array 
(
    [0] => Array 
     (
      [0] => a 
      [1] => b 
      [3] => c 
      [4] => f 
     ) 

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

) 

DEMO

+0

спасибо, но, как я уже сказал, я пытался избежать вложенных циклов. –

+0

@AlexKneller Любая конкретная причина? Сколько предметов вы имеете в виду? – h2ooooooo

1

Кажется, что у ваших внутренних массивов всегда есть 2 предмета. поэтому вложенные петли не нужны. Вот решение, которое я изначально писал в JS, но он должен работать так же хорошо и наиболее эффективным в PHP:

$arr=[["a","b"],["b","c"],["d","e"],["f","c"],["h","e"]]; 
$output = []; 
$outputKeys = []; 
$counter = 0; 
foreach($arr as $V) { 
    if(!isset($outputKeys[$V[0]]) && !isset($outputKeys[$V[1]])) { 
     $output[$counter] = [$V[0], $V[1]]; 
     $outputKeys[$V[0]] = &$output[$counter]; 
     $outputKeys[$V[1]] = &$output[$counter]; 
     $counter++; 
    } 
    elseif(isset($outputKeys[$V[0]]) && !isset($outputKeys[$V[1]])) { 
     array_push($outputKeys[$V[0]], $V[1]); 
     $outputKeys[$V[1]] = &$outputKeys[$V[0]]; 
    } 
    elseif(!isset($outputKeys[$V[0]]) && isset($outputKeys[$V[1]])) { 
     array_push($outputKeys[$V[1]], $V[0]); 
     $outputKeys[$V[0]] = &$outputKeys[$V[1]]; 
    } 
} 
var_dump($output); // [["a","b","c","f"],["d","e","h"]] 

DEMO (click the execute button)

Указатели являются вашими друзьями. Используйте их :)

Смежные вопросы