js获取php多维数组,PHP 多维数组中的 array_find

过渡

最近在开始使用 ThinkPHP 5.1 进行一系列开发工作,因为之前是使用 Laravel 进行开发,像是标题中的这种小问题都在 Laravel 中很容易实现。直接使用 array_first 方法进行查找即可。

快速实现

但是在 ThinkPHP 中 并没有提供类似方法进行快速处理,所以有需要来重复造轮子了?

至此想到的第一个方法就是使用 array_search 不过这个方法中官方提供的方案仅用于简单的一维数组搜索,而且返回的也只是 index 并不是找到的结果,淡然通过 index 我们也可以取出项目来,在 PHP 5.5 带来的新方法 array_column,可以方便的实现二维搜索 在这里的用户笔记 为我们提供了一个小的示例。

$userdb=Array

(

(0) => Array

(

(uid) => '100',

(name) => 'Sandra Shush',

(url) => 'urlof100'

),

(1) => Array

(

(uid) => '5465',

(name) => 'Stefanie Mcmohn',

(pic_square) => 'urlof100'

),

(2) => Array

(

(uid) => '40489',

(name) => 'Michael',

(pic_square) => 'urlof40489'

)

);

$key = array_search(40489, array_column($userdb, 'uid'));

并且赢得了 800+ 的赞赏,到这里可能你会觉得 通过这个方式取到 index 然后用 index 取出来就行了。

一些🌰

但是,如果你再往下翻一下,你会看到另一条用户笔记 ,这条用户笔记告诉我们 当我们使用这种方式来实现二维搜索时你 PHP 版本 必须要在 5.5 + ,作者同时告诉我们

Since array_column() will produce a resulting array; it won't preserve your multi-dimentional array's keys. So if you check against your keys, it will fail.

机翻一下 :由于array_column()将产生一个新的数组; 它不会保留多维数组的原来的键。 因此,如果您检查您的键,它将失败。

然后作者也为我们提供了一个🌰

$people = array(

2 => array(

'name' => 'John',

'fav_color' => 'green'

),

5 => array(

'name' => 'Samuel',

'fav_color' => 'blue'

)

);

$found_key = array_search('blue', array_column($people, 'fav_color')); // 1

// Here, you could expect that the $found_key would be "5" but it's NOT. It will be 1. Since it's the second element of the produced array by the array_column() function.

// 机翻一下:在这里,你预期 $found_key 的将是“5”,但它不是,它将是1.因为它是array_column()函数生成的数组的第二个元素。

// 另外 作者还提到了

// Secondly, if your array is big, I would recommend you to first assign a new variable so that it wouldn't call array_column() for each element it searches. For a better performance, you could do;

// 机翻一下:其次,如果您的数组很大,我建议您先分配一个新变量,这样它就不会为它搜索的每个元素调用array_column()。 为了获得更好的性能,你可以做到;

$colors = array_column($people, 'fav_color');

$found_key = array_search('blue', $colors);

看完了这些提示,你已经发现了这其中的坑,然而,这并没有结束,因为如果数据不够纯净的话,你用 array_search 实现的功能可能就只局限于 in_array 。

而且,尽管到了这里,还会遇到另外一个坑,先看🌰

$userdb = array(

0 => array(

'uid' => 100,

'name' => 'Sandra Shush',

'url' => 'urlof100'

),

'8' => array(

'uid' => 5465,

'name' => 'Stefanie Mcmohn',

'pic_square' => 'urlof100'

),

'3' => Array(

// 'uid' => 5555,

'name' => 'Michael',

'pic_square' => 'urlof40489'

),

'6' => Array(

'uid' => 40489,

'name' => 'Michael',

'pic_square' => 'urlof40489'

)

);

$found_key = array_search(40489, array_column($userdb, 'uid'));

在这里 猜想一下 $found_key 会是什么?答案是: 2。

??? ,因为当在执行 array_column() 时,第三个元素,也就是键为3的数据中 uid 被注释了,这时候 PHP 就会忽略它,并不会被保留索引位置,所以这时候结果只有 3 个元素,第四个向上替补了,因为数组索引是 0 开始,所以 2 就相当于第 3 个元素了。

大家都是怎么做的?

在 array_search 的用户笔记区中,看到了很多都是数组循环并比对后返回,比如这个,但是这样又遇到一些局限性问题,这时候我们又想到了 Laravel 中把自主权交给调用者,由调用者在匿名方法内进行处理并返回 bool 值 进行处理。

至此,看回 Laravel 的 array_fisrt 方法,通过 Laravel 源码可以看到 array_first 是 Arr::fisrt 方法的一个包装,在这里我们可以看到 Laravel 的实现方式,在这一小段代码中 还看到了另一个方法 value(),可以看到,这个方法就是判断是否是一个匿名方法,如果是就执行方法并返回,不是就直接返回。

public static function first($array, callable $callback = null, $default = null)

{

if (is_null($callback)) {

if (empty($array)) {

return value($default);

}

foreach ($array as $item) {

return $item;

}

}

foreach ($array as $key => $value) {

if (call_user_func($callback, $value, $key)) {

return $value;

}

}

return value($default);

}

if (! function_exists('value')) {

/**

* Return the default value of the given value.

*

* @param mixed $value

* @return mixed

*/

function value($value)

{

return $value instanceof Closure ? $value() : $value;

}

}

看到这里,几乎是比较完整的实现,在这里还想到了另外一个和助手函数有关的项目:Underscore.php

这是一个 PHP 的方法库,也可以算是是 JS中的 underscore.js和 loadsh、ramda 的 PHP 实现。

在这个项目中我们看到了实现方式

public static function find($array, Closure $closure)

{

foreach ($array as $key => $value) {

if ($closure($value, $key)) {

return $value;

}

}

return;

}

这里的实现更为简单,最终也实现了我们想要的结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值