如何在 PHP 中使用索引数组的键过滤关联数组?

新手上路,请多包涵

array_filter() 中的回调函数只传入数组的值,而不是键。

如果我有:

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

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

删除 $my_array 中所有不在 $allowed 数组中的键的最佳方法是什么?

期望的输出:

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

原文由 maček 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 442
2 个回答

PHP 5.6 向 array_filter()flag 引入了第三个参数,您可以将其设置为 ARRAY_FILTER_USE_KEY 以通过键而不是值过滤:

 $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
);

由于 PHP 7.4 引入了箭头函数,我们可以使它更简洁:

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

显然这不像 array_intersect_key($my_array, array_flip($allowed)) 那样优雅,但它确实提供了对密钥执行任意测试的额外灵活性,例如 $allowed 可以包含正则表达式模式而不是普通字符串。

您还可以使用 ARRAY_FILTER_USE_BOTH 将值和键都传递给您的过滤器函数。这是一个基于第一个的人为示例,但请注意,我不建议这样使用 $allowed 编码过滤规则:

 $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']

原文由 Richard Turner 发布,翻译遵循 CC BY-SA 4.0 许可协议

我使用了一个小的“Utils”类,我在其中添加了两个过滤器静态函数来使用拒绝列表或允许列表过滤数组。

 <?php

class Utils {

  /**
   * Filter an array based on a allowlist of keys
   *
   * @param array $array
   * @param array $allowlist
   *
   * @return array
   */
  public static function array_keys_allowlist( array $array, array $allowlist ): array {
    return array_intersect_key( $array, array_flip( $allowlist ) );
  }

  /**
   * Filter an array based on a denylist of keys
   *
   * @param array $array
   * @param array $denylist
   *
   * @return array
   */
  public static function array_keys_denylist( array $array, array $denylist ): array {
    return array_diff_key($array,array_flip($denylist));
  }

}

然后你可以像这样使用它

<?php

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

$my_array = Utils::array_keys_allowlist($my_array,  $allowed)

原文由 gagarine 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题