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-?

Alex
quelle
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);
}
Entwickler-Sid
quelle
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();
}
erisco
quelle
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...
    }
}
Matías Cánepa
quelle
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

Suresh Velusamy
quelle
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')
biziclop
quelle
14
foreach($arr as $key => $value)
{
   if(preg_match('/^foo-/', $key))
   {
        // You can access $value or create a new array based off these values
   }
}
Tim Cooper
quelle
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.

Keyur
quelle
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
)
*/
Netsurfer
quelle
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