Yii2.0 数组助手类

use yii\helpers\ArrayHelper;

数组助手类

获取值

$value = ArrayHelper::getValue($array, 'foo.bar.name'); // 若不存在 默认返回 null
// $value = ArrayHelper::getValue($array, 'foo.bar.name', 'unkwon');

$fullName = ArrayHelper::getValue($user, function ($user, $defaultValue) {
	return $user->firstName . ' ' . $user->lastName;
});

删除指定键值

$array = ['type' => 'A', 'options' => [1, 2]];
$type = ArrayHelper::remove($array, 'type');

检查键名的存在

和array_key_exists差不多,除了 它还可支持大小写不敏感的键名比较

$data1 = [
    'userName' => 'Alex',
];

$data2 = [
    'username' => 'Carsten',
];

if (!ArrayHelper::keyExists('username', $data1, false) || !ArrayHelper::keyExists('username', $data2, false)) {
    echo "Please provide username.";
}

检索列

通常你要从多行数据或者多个对象构成的数组中获取某列的值

$data = [
    ['id' => '123', 'data' => 'abc'],
    ['id' => '345', 'data' => 'def'],
];
$ids = ArrayHelper::getColumn($array, 'id');
// 结果 ['123', '345']。

// 如果需要额外的转换或者取值的方法比较复杂, 第二参数可以指定一个匿名函数:

$result = ArrayHelper::getColumn($array, function ($element) {
    return $element['id'];
});

重建数组索引

输入的数组应该是多维数组或者是一个对象数组。 键名 可以是子 数组的键名对象的属性名, 也可以是一个返回给定元素数组键值的匿名函数

$array = [
    ['id' => '123', 'data' => 'abc', 'device' => 'laptop'],
    ['id' => '345', 'data' => 'def', 'device' => 'tablet'],
    ['id' => '345', 'data' => 'hgi', 'device' => 'smartphone'],
];
$result = ArrayHelper::index($array, 'id');

// 返回
[
'123' => ['id' => '123', 'data' => 'abc', 'device' => 'laptop'],
'345' => ['id' => '345', 'data' => 'hgi', 'device' => 'smartphone']
// 键名相同会被覆盖
]

// 匿名函数
$result = ArrayHelper::index($array, function ($element) {
return $element['id'];
});

// 相同键名不覆盖
$result = ArrayHelper::index($array, null, 'id');

[
    '123' => [
        ['id' => '123', 'data' => 'abc', 'device' => 'laptop']
    ],
    '345' => [ // all elements with this index are present in the result array
        ['id' => '345', 'data' => 'def', 'device' => 'tablet'],
        ['id' => '345', 'data' => 'hgi', 'device' => 'smartphone'],
    ]
]

// 指定键名 匿名函数
$result = ArrayHelper::index($array, 'data', [function ($element) {
	return $element['id'];
}, 'device']);
// 返回
[
    '123' => [
        'laptop' => [
            'abc' => ['id' => '123', 'data' => 'abc', 'device' => 'laptop']
        ]
    ],
    '345' => [
        'tablet' => [
            'def' => ['id' => '345', 'data' => 'def', 'device' => 'tablet']
        ],
        'smartphone' => [
            'hgi' => ['id' => '345', 'data' => 'hgi', 'device' => 'smartphone']
        ]
    ]
]

建立哈希表

为了从一个多维数组或者一个对象数组中建立一个映射表(键值对)

$array = [
    ['id' => '123', 'name' => 'aaa', 'class' => 'x'],
    ['id' => '124', 'name' => 'bbb', 'class' => 'x'],
    ['id' => '345', 'name' => 'ccc', 'class' => 'y'],
);

$result = ArrayHelper::map($array, 'id', 'name');
// 结果是:
[
    '123' => 'aaa',
    '124' => 'bbb',
    '345' => 'ccc',
]

$result = ArrayHelper::map($array, 'id', 'name', 'class');
// 结果是:
[
    'x' => [
        '123' => 'aaa',
        '124' => 'bbb',
    ],
    'y' => [
        '345' => 'ccc',
    ],
]

多维排序

$data = [
    ['age' => 30, 'name' => 'Alexander'],
    ['age' => 30, 'name' => 'Brian'],
    ['age' => 19, 'name' => 'Barney'],
];
ArrayHelper::multisort($data, ['age', 'name'], [SORT_ASC, SORT_DESC]);
// 返回
[
    ['age' => 19, 'name' => 'Barney'],
    ['age' => 30, 'name' => 'Brian'],
    ['age' => 30, 'name' => 'Alexander'],
];
// 第二个参数指定排序的键名,如果是单键名的话可以是字符串,如果是多键名则是一个数组, 或者是如下例所示的一个匿名函数:

ArrayHelper::multisort($data, function($item) {
    return isset($item['age']) ? ['age', 'name'] : 'name';
});
//第三个参数表示增降顺序。单键排序时,它可以是 SORT_ASC 或者 SORT_DESC 之一。如果是按多个键名排序,你可以用一个数组为 各个键指定不同的顺序。

//第四个参数 是PHP的排序标识,可使用的值和调用PHP sort() 函数时传递的值一样。

bool sort ( array &$array [, int $sort_flags = SORT_REGULAR ] )

检测数组类型

// 是`索引数组`还是`联合数组`?
// 不指定键名的数组
$indexed = ['Qiang', 'Paul'];
echo ArrayHelper::isIndexed($indexed);

// 所有键名都是字符串
$associative = ['framework' => 'Yii', 'version' => '2.0'];
echo ArrayHelper::isAssociative($associative);

HTML 编码和解码值

$encoded = ArrayHelper::htmlEncode($data);
$decoded = ArrayHelper::htmlDecode($data);
//默认情况只会对值做编码。通过给第二个参数传 false ,你也可以对键名做编码。

//编码将默认使用应用程序的字符集,你可以通过第三个参数指定该字符集。

合并数组

/**
* 将两个或者多个数组递归式的合并为一个数组。
* 如果每个数组有一个元素的键名相同,
* 那么后面元素的将覆盖前面的元素(不同于 array_merge_recursive)。
* 如果两个数组都有相同键名的数组元素(译者注:嵌套数组)
* 则将引发递归合并。
* 对数值型键名的元素,后面数组中的这些元素会被追加到前面数组中。
* @param array $a 被合并的数组
* @param array $b 合并的数组,你可以在第三、第四个
* 参数中指定另外的合并数组,等等
* @return 合并的结果数组 (原始数组不会被改变)
*/
public static function merge($a, $b)

判断是否存在数组或对象元素

// true
ArrayHelper::isIn('a', ['a']);
// true
ArrayHelper::isIn('a', new(ArrayObject['a']));

// true
ArrayHelper::isSubset(new(ArrayObject['a', 'c']), new(ArrayObject['a', 'b', 'c'])

对象转换为数组

你经常要将一个对象或者对象的数组转换成一个数组,常见的情形是,为了通过REST API提供数据数组(或其他使用方式), 将AR模型(活动记录模型)转换成数组。如下代码可完成这个工作:

$posts = Post::find()->limit(10)->all();
$data = ArrayHelper::toArray($posts, [
    'app\models\Post' => [
        'id',
        'title',
        // the key name in array result => property name
        'createTime' => 'created_at',
        // the key name in array result => anonymous function
        'length' => function ($post) {
            return strlen($post->content);
        },
    ],
]);

第一个参数包含我们想要转换的数据,在本例中,我们要转换一个叫 Post 的 AR 模型。

第二个参数是每个类的转换映射表,我们在此设置了一个Post 模型的映射。 每个映射数组包含一组的映射,每个映射可以是:

一个要包含的照原样的字段名(和类中属性的名称一致);

一个由你可随意取名的键名和你想从中取值的模型列名组成的键值对;

一个由你可随意取名的键名和有返回值的回调函数组成的键值对;

这上面的转换结果将会是:

[
    'id' => 123,
    'title' => 'test',
    'createTime' => '2013-01-01 12:00AM',
    'length' => 301,
]

也可以在一个特定的类中实现Arrayable接口, 从而为其对象提供默认的转换成数组的方法。

检测一个元素在数组或一组元素的一个子集

ArrayHelper::isIn('a', ['a']);
// true

ArrayHelper::isIn('a', new(ArrayObject['a']));
// true

ArrayHelper::isSubset(new(ArrayObject['a', 'c']), new(ArrayObject['a', 'b', 'c'])
// true

参考:

-http://www.yiichina.com/doc/guide/2.0/helper-array#retrieving-columns




导航