PHP - Holen Sie sich alle Schlüssel aus einem Array, die mit einer bestimmten Zeichenfolge beginnen


81

Ich habe ein Array, das so aussieht:

array(
  'abc' => 0,
  'foo-bcd' => 1,
  'foo-def' => 1,
  'foo-xyz' => 0,
  // ...
)

Wie kann ich nur die Elemente erhalten, die mit beginnen foo-?


3
Ein Array mit solchen Präfixen zu haben, ist ein Codegeruch. Extrahieren Sie diese Werte in ein Objekt, das diese Werte enthält, oder setzen Sie das Präfix zumindest auf ein Array und fügen Sie die Werte hinzu.
Gordon

Antworten:


19
$arr_main_array = array('foo-test' => 123, 'other-test' => 456, 'foo-result' => 789);

foreach($arr_main_array as $key => $value){
    $exp_key = explode('-', $key);
    if($exp_key[0] == 'foo'){
         $arr_result[] = $value;
    }
}

if(isset($arr_result)){
    print_r($arr_result);
}

17
Bevor Sie diese Lösung wählen, ist die folgende besser. Verwenden Sie niemals Array-Funktionen, bei denen eine einfache String-Funktion ausreicht. String-Funktionen sind viel schneller. Dies wird bei großen Arrays "verzögert".
Martijn

2
Ich sehe keinen Sinn darin, die Array-Schlüssel in Arrays zu zerlegen. Es handelt sich um Zeichenfolgen, und bei der ursprünglichen Frage wird nur nach einem Zeichenfolgenpräfix gefragt. Auch OP fragt nach "den Elementen" und nicht nur nach den Werten, so dass das numerisch indizierte Ergebnis unbrauchbar wird - die Schlüssel sind hier eindeutig wichtig, wobei die Werte (vermutlich) anonyme 1/0 Flags sind.
Jason

125

Funktionsansatz:

Nehmen Sie eine array_filter_keyArt Funktion aus den Kommentaren in http://php.net/array_filter oder schreiben Sie Ihre eigene. Dann könnten Sie tun:

$array = array_filter_key($array, function($key) {
    return strpos($key, 'foo-') === 0;
});

Verfahrensansatz:

$only_foo = array();
foreach ($array as $key => $value) {
    if (strpos($key, 'foo-') === 0) {
        $only_foo[$key] = $value;
    }
}

Verfahrensansatz unter Verwendung von Objekten:

$i = new ArrayIterator($array);
$only_foo = array();
while ($i->valid()) {
    if (strpos($i->key(), 'foo-') === 0) {
        $only_foo[$i->key()] = $i->current();
    }
    $i->next();
}

20
Hinweis PHP 5.6 fügt das Flag ARRAY_FILTER_USE_KEY hinzu array_filter(), das Sie verwenden können, anstatt eine benutzerdefinierte array_filter_key()Funktion bereitzustellen .
Jason

4
Können Sie bitte einfach die Funktion array_filter_key zu Ihrem Beispiel hinzufügen? Ich bekam immer wieder einen Fehler und musste Ihren Beitrag mehrmals neu lesen, bevor ich meinen Fehler erkannte. Es ist nicht schwer, nur den Code zu posten, einen Klick zu speichern und jemandem Zeit bei der Fehlerbehebung zu sparen. Vielen Dank.
Chris Sprague

38

So würde ich es machen, obwohl ich Ihnen keinen effizienteren Rat geben kann, bevor ich nicht verstanden habe, was Sie mit den Werten tun möchten, die Sie erhalten.

$search = "foo-";
$search_length = strlen($search);
foreach ($array as $key => $value) {
    if (substr($key, 0, $search_length) == $search) {
        ...use the $value...
    }
}

2
Sie können auch verwenden:foreach ($array as $key => $value) { if (0 === strpos($key, 'foo-')) { ...use the $value... } }
Iago

Die "4" muss hier auf die Länge "foo-" eingestellt werden.
Jason

20

Ich habe einfach die array_filterFunktion verwendet, um die Lösung wie folgt zu erreichen

<?php

$input = array(
    'abc' => 0,
    'foo-bcd' => 1,
    'foo-def' => 1,
    'foo-xyz' => 0,
);

$filtered = array_filter($input, function ($key) {
    return strpos($key, 'foo-') === 0;
}, ARRAY_FILTER_USE_KEY);

print_r($filtered);

Ausgabe

Array
(
    [foo-bcd] => 1
    [foo-def] => 1
    [foo-xyz] => 0
)

Für Live-Check https://3v4l.org/lJCse


1
Beachten Sie, dass hierfür mindestens PHP 5.6.0 erforderlich ist (aufgrund der Verwendung der Konstanten ARRAY_FILTER_USE_KEY). In früheren Versionen können Sie verwenden: [Code]
Netsurfer

19

Ab PHP 5.3 können Sie die preg_filterFunktion verwenden: hier

$unprefixed_keys = preg_filter('/^foo-(.*)/', '$1', array_keys( $arr ));

// Result:
// $unprefixed_keys === array('bcd','def','xyz')

14
foreach($arr as $key => $value)
{
   if(preg_match('/^foo-/', $key))
   {
        // You can access $value or create a new array based off these values
   }
}

3
Eine Regex ist in diesem Fall nicht wirklich notwendig. Die substr-Methode ist etwas effizienter
jfoucher

2
@jfoucher: Das stimmt, aber persönlich ist es einfacher zu lesen.
Tim Cooper

2
Es ist zwar flexibler, kostet jedoch die Notwendigkeit, spezielle Preg-Zeichen zu umgehen, wenn Sie keine Übereinstimmung mit regulären Ausdrücken durchführen möchten. Also mit Vorsicht verwenden. Ich würde vorschlagen, dass Sie REs nur verwenden, wenn Sie REs benötigen.
Jason

7

Änderung des Funktionsansatzes von erisco ,

array_filter($signatureData[0]["foo-"], function($k) {
    return strpos($k, 'foo-abc') === 0;
}, ARRAY_FILTER_USE_KEY);

das hat bei mir funktioniert.


Gibt es einen Unterschied in der Leistung oder Nützlichkeit gegenüber der von @erisco bereitgestellten Version array_filter_key?
Jeffrey die Giraffe

Nee. Es sollte keinen Unterschied in der Leistung geben, denke ich. @ MaciekSemik
Keyur

1
Dies ist eine PHP-Kernfunktion, daher sollte sie bevorzugt werden.
Jeremy John

3

Zusätzlich zu der obigen Antwort von @Suresh Velusamy (für die mindestens PHP 5.6.0 erforderlich ist) können Sie Folgendes verwenden, wenn Sie eine frühere Version von PHP verwenden:

<?php

$input = array(
    'abc' => 0,
    'foo-bcd' => 1,
    'foo-def' => 1,
    'foo-xyz' => 0,
);

$filtered = array_filter(array_keys($input), function($key) {
    return strpos($key, 'foo-') === 0;
});

print_r($filtered);

/* Output:
Array
(
    [1] => foo-bcd
    [2] => foo-def
    [3] => foo-xyz
)
// the numerical array keys are the position in the original array!
*/

// if you want your array newly numbered just add:
$filtered = array_values($filtered);

print_r($filtered);

/* Output:
Array
(
    [0] => foo-bcd
    [1] => foo-def
    [2] => foo-xyz
)
*/

Bitte beachten Sie (oder zumindest für mich), dass dies nur die übereinstimmenden Array-Schlüssel zurückgibt. Die Antwort unten von @ suresh-velusamy extrahiert das tatsächliche Array mit dem ursprünglichen $key => $valuePaar. Es ist in der Ausgabe dieser Antwort angegeben, wurde aber noch nicht explizit erwähnt
Martie
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.