455 Stimmen

Array nach seinen Schlüsseln filtern, indem man ein Array von erlaubten Schlüsseln verwendet

Die Rückruffunktion in array_filter() übergibt nur die Werte des Arrays, nicht die Schlüssel.

Wenn ich es habe:

$my_array = array("foo" => 1, "hello" => "world");

$allowed = array("foo", "bar");

Wie lösche ich am besten alle Schlüssel in $my_array die sich nicht in der $allowed Array?

Gewünschter Output:

$my_array = array("foo" => 1);

528voto

Vincent Savard Punkte 33059

Mit array_intersect_key y array_flip :

var_dump(array_intersect_key($my_array, array_flip($allowed)));

array(1) {
  ["foo"]=>
  int(1)
}

469voto

Richard Turner Punkte 11994

Mit PHP 5.6 wurde ein dritter Parameter für array_filter() , flag , die Sie auf ARRAY_FILTER_USE_KEY um nach dem Schlüssel statt nach dem Wert zu filtern:

$my_array = ['foo' => 1, 'hello' => 'world'];
$allowed  = ['foo', 'bar'];
$filtered = array_filter(
    $my_array,
    function ($key) use ($allowed) {
        // N.b. in_array() is notorious for being slow 
        return in_array($key, $allowed);
    },
    ARRAY_FILTER_USE_KEY
);

Seit PHP 7.4 die Pfeilfunktionen eingeführt hat, können wir dies knapper fassen:

$my_array = ['foo' => 1, 'hello' => 'world'];
$allowed  = ['foo', 'bar'];
$filtered = array_filter(
    $my_array,
    fn ($key) => in_array($key, $allowed),
    ARRAY_FILTER_USE_KEY
);

Natürlich ist das nicht so elegant wie array_intersect_key($my_array, array_flip($allowed)) Es bietet jedoch die zusätzliche Flexibilität, einen beliebigen Test gegen den Schlüssel durchzuführen, z. B. $allowed könnte Regex-Muster anstelle von einfachen Zeichenketten enthalten.

Sie können auch Folgendes verwenden ARRAY_FILTER_USE_BOTH um sowohl den Wert als auch den Schlüssel an Ihre Filterfunktion zu übergeben. Hier ist ein erfundenes Beispiel, das auf dem ersten basiert, aber beachten Sie, dass ich nicht empfehlen würde, Filterregeln zu kodieren, die $allowed auf diese Weise:

$my_array = ['foo' => 1, 'bar' => 'baz', 'hello' => 'wld'];
$allowed  = ['foo' => true, 'bar' => true, 'hello' => 'world'];
$filtered = array_filter(
    $my_array,
    fn ($val, $key) => isset($allowed[$key]) && (
        $allowed[$key] === true || $allowed[$key] === $val
    ),
    ARRAY_FILTER_USE_BOTH
); // ['foo' => 1, 'bar' => 'baz']

10voto

COil Punkte 6490

Hier ist eine flexiblere Lösung unter Verwendung eines Verschlusses:

$my_array = array("foo" => 1, "hello" => "world");
$allowed = array("foo", "bar");
$result = array_flip(array_filter(array_flip($my_array), function ($key) use ($allowed)
{
    return in_array($key, $allowed);
}));
var_dump($result);

Ausgänge:

array(1) {
  'foo' =>
  int(1)
}

In der Funktion können Sie also weitere spezifische Tests durchführen.

4voto

Alastair Punkte 6659

Hier ist eine weniger flexible Alternative mit unset() :

$array = array(
    1 => 'one',
    2 => 'two',
    3 => 'three'
);
$disallowed = array(1,3);
foreach($disallowed as $key){
    unset($array[$key]);
}

Das Ergebnis von print_r($array) sein:

Array
(
    [2] => two
)

Dies gilt nicht, wenn Sie die gefiltert Werte für die spätere Verwendung, aber ordentlicher, wenn Sie sicher sind, dass Sie sie nicht brauchen.

4voto

Nicolas Zimmer Punkte 404

Wenn Sie nach einer Methode suchen, um ein Array nach einer in den Schlüsseln vorkommenden Zeichenkette zu filtern, können Sie diese verwenden:

$mArray=array('foo'=>'bar','foo2'=>'bar2','fooToo'=>'bar3','baz'=>'nope');
$mSearch='foo';
$allowed=array_filter(
    array_keys($mArray),
    function($key) use ($mSearch){
        return stristr($key,$mSearch);
    });
$mResult=array_intersect_key($mArray,array_flip($allowed));

Das Ergebnis von print_r($mResult) ist

Array ( [foo] => bar [foo2] => bar2 [fooToo] => bar3 )

Eine Adaption dieser Antwort, die reguläre Ausdrücke unterstützt

function array_preg_filter_keys($arr, $regexp) {
  $keys = array_keys($arr);
  $match = array_filter($keys, function($k) use($regexp) {
    return preg_match($regexp, $k) === 1;
  });
  return array_intersect_key($arr, array_flip($match));
}

$mArray = array('foo'=>'yes', 'foo2'=>'yes', 'FooToo'=>'yes', 'baz'=>'nope');

print_r(array_preg_filter_keys($mArray, "/^foo/i"));

Ausgabe

Array
(
    [foo] => yes
    [foo2] => yes
    [FooToo] => yes
)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X