2017-01-08 3 views
1

Ich habe zwei mehrdimensionale Arrays:überprüfen, ob Array in zwei mehrdimensionales Array ist

Haystack

$haystack = array (
    0 => array (
    "child_element_id" => 11 
    "answer_id" => 15 
), 
    1 => array (
    "child_element_id" => 12 
    "answer_id" => 17 
), 
    2 => array (
    "child_element_id" => 13 
    "answer_id" => 21 
) 
) 

Nadel

$needle = array (
    0 => array (
    "child_element_id" => 12 
    "answer_id" => 17 
), 
    1 => array (
    "child_element_id" => 13 
    "answer_id" => 21 
) 
) 

Ich möchte, wenn alle wichtigen Werte von Array überprüfen "Needle" existiert im Array "Haystack". Was ist die beste Vorgehensweise dafür? Vielen Dank!

+0

Hat 'Nadel' einen konstanten Schlüsselnamen? – Mohammad

+0

Tut mir leid, ja es tut "child_answers", um genau zu sein –

Antwort

1

Ziemlich einfach 01 unter Verwendung vonda Nadel kann ein Array sein:

$found = 0; 
foreach($needle as $array) { 
    if(in_array($array, $haystack, true)) { 
     $found++; 
    } 
} 
if($found === count($needle)) { 
    echo 'all needles were found in haystack'; 
} 

Oder vielleicht:

$found = true; 
foreach($needle as $array) { 
    if(!in_array($array, $haystack, true)) { 
     $found = false; 
     break; 
    } 
} 
if($found) { 
    echo 'all needles were found in haystack'; 
} 

Sie sogar array_search() nutzen könnten, wie Sie auch ein Array für Nadel verwenden können, keine Notwendigkeit, zwei Schleifen laufen.

Mit serialize():

if(count(array_map('unserialize', 
     array_intersect(array_map('serialize', $needle), 
         array_map('serialize',$haystack)))) == count($needle)) 
{ 
          echo 'all needles were found in haystack'; 
} 
  • serialize() den inneren Anordnungen beiden Arrays und berechnen den Schnittpunkt (gemeinsame Innen arrays)
  • unserialize() das Ergebnis und vergleicht die count() mit der Zählung von $needle
1

Sie könnten diese Funktion nutzen:

function array_in_array(array $needle, array $haystack) { 
foreach($needle as $nearr) { 
    foreach ($haystack as $array) { 
    //check arrays for equality 
    if(count($needle) == count($array)) { 
     $needleString = serialize($needle); 
     $arrayString = serialize($array); 
     if(strcmp($needleString, $arrayString) == 0 ) 
     return true; 
     } 
} 
    return false; 
} 
2

fast eine Lösung:
@shalvah einen guten Ausgangspunkt gab. Jedoch in der vorgeschlagenen Lösung vergaß er über die Elemente des $needle Array Schleife wie unten dargestellt:

function array_in_array($neearr,$haystack) { 
    foreach ($neearr as $needle){ 
    foreach ($haystack as $array) { 
     //check arrays for equality 
     if(count($needle) == count($array)) { 
     $needleString = serialize($needle); 
     $arrayString = serialize($array); 
     echo "$needleString||$arrayString<br>"; 
     if(strcmp($needleString, $arrayString) == 0) return true; 
     } 
     return false; 
    } 
    } 
} 

Aber auch so ist dies nicht vollständig „wasserdicht“. In Fällen, in denen Elemente der „Nadel“ Arrays in einer anderen Reihenfolge (Sequenz) erscheinen die serialze() -function unterschiedlichen Zeichenfolgen produzieren und zu falschen Negativen führen, wie in der unten stehenden exampe gezeigt:

$hay=array(array('a'=>'car','b'=>'bicycle'), 
     array('a'=>'bus','b'=>'truck'), 
     array('a'=>'train','b'=>'coach')); 

$nee1=array(array('a'=>'car','b'=>'bicycle'), 
     array('a'=>'train','b'=>'coach')); 

$nee2=array(array('b'=>'bicycle','a'=>'car'), // different order of elements! 
     array('a'=>'train','b'=>'coach')); 

echo array_in_array($nee1,$hay); // true 
echo array_in_array($nee2,$hay); // false (but should be true!) 

eine leicht bessere Lösung
Dieses Problem kann dadurch gelöst werden, erste Sortieranlage (ksort(): Sortieren nach Schlüsselwert), um alle Elemente aller „Nadel“ Arrays vor serialize -Ing sie:

function array_in_array($neearr,$haystack) { 
    $haystackstrarr = array_map(function($array){ksort($array);return serialize($array);},$haystack); 
    foreach ($neearr as $needle){ 
    ksort($needle); 
    $needleString = serialize($needle); 
    foreach ($haystackstrarr as $arrayString){ 
     if(strcmp($needleString, $arrayString) == 0) return true; 
    } 
    return false; 
    } 
} 

echo array_in_array($nee1,$hay); // true 
echo array_in_array($nee2,$hay); // true 
+0

Wäre es nicht einfacher, die Funktion rekursiv aufzurufen? die verarbeiteten Daten als sekundäres Attribut übergeben? –

+0

@DarylGill: Ganz richtig! Auch wenn ich * einige * in meinem Code sortierte, wird es höchstwahrscheinlich nicht zuverlässig mit tieferen "Nadel" -Arrays funktionieren. Dies war nur ein "schneller Schuss", der auf der Basis von Shalvahs Post gemacht wurde. Ein rekursiver Code ist sehr wahrscheinlich der bessere Ansatz. Vielleicht kannst du ein kleines Beispiel zusammenstellen ;-) ... – cars10m

+0

@ Autos10 Looping über die Nadel-Array? Ist '$ näser' 1D nicht' $ haystack' 2D? – shalvah