数组辅助函数

数组辅助函数提供了若干函数,旨在简化较为复杂的数组操作。它无意重复 PHP 现有的任何功能——除非这样做能大幅简化这些功能的使用。

加载此辅助函数

使用以下代码加载此辅助函数:

helper('array');

可用函数

提供以下函数:

参数:
  • $search (string) -- 描述如何搜索数组的点号表示法字符串

  • $values (array) -- 要搜索的数组

返回:

在数组中找到的值,如果没有找到则为 null

返回类型:

mixed

此方法允许你使用点号表示法在数组中搜索特定键,并允许使用 * 通配符。给定以下数组:

$data = [
    'foo' => [
        'buzz' => [
            'fizz' => 11,
        ],
        'bar' => [
            'baz' => 23,
        ],
    ],
];

我们可以使用搜索字符串 foo.buzz.fizz 来定位 fizz 的值。同样,baz 的值可以通过 foo.bar.baz 找到:

// Returns: 11
$fizz = dot_array_search('foo.buzz.fizz', $data);

// Returns: 23
$baz = dot_array_search('foo.bar.baz', $data);

你可以使用星号 (*) 作为通配符来替换任何段。当找到时,它将搜索所有子节点直到找到它。当你不知道值,或者值有数字索引时,这很方便:

// Returns: 23
$baz = dot_array_search('foo.*.baz', $data);

如果数组键包含点号 (.),则该键可以用反斜杠 (\) 转义:

$data = [
    'foo' => [
        'bar.baz' => 23,
    ],
    'foo.bar' => [
        'baz' => 43,
    ],
];

// Returns: 23
$barBaz = dot_array_search('foo.bar\.baz', $data);
// Returns: 43
$fooBar = dot_array_search('foo\.bar.baz', $data);

备注

在 v4.2.0 之前,dot_array_search('foo.bar.baz', ['foo' => ['bar' => 23]]) 由于一个错误返回 23。 v4.2.0 及更高版本返回 null

参数:
  • $key (mixed) -- 目标键

  • $array (array) -- 要搜索的数组

返回:

在数组中找到的值,如果没有找到则为 null

返回类型:

mixed

返回具有键值的元素在不确定深度数组中的值

array_sort_by_multiple_keys(array &$array, array $sortColumns)
参数:
  • $array (array) -- 要排序的数组(按引用传递)。

  • $sortColumns (array) -- 要排序的数组键和相应的 PHP 排序标志作为关联数组。

返回:

排序是否成功。

返回类型:

bool

此方法通过一个或多个键的值以分层方式对多维数组的元素进行排序。采用以下数组,可能从模型的 find() 函数返回:

$players = [
    0 => [
        'name'     => 'John',
        'team_id'  => 2,
        'position' => 3,
        'team'     => [
            'id'    => 1,
            'order' => 2,
        ],
    ],
    1 => [
        'name'     => 'Maria',
        'team_id'  => 5,
        'position' => 4,
        'team'     => [
            'id'    => 5,
            'order' => 1,
        ],
    ],
    2 => [
        'name'     => 'Frank',
        'team_id'  => 5,
        'position' => 1,
        'team'     => [
            'id'    => 5,
            'order' => 1,
        ],
    ],
];

现在通过两个键对此数组进行排序。注意,该方法支持点号表示法来访问更深层级的数组值,但不支持通配符:

array_sort_by_multiple_keys($players, [
    'team.order' => SORT_ASC,
    'position'   => SORT_ASC,
]);

$players 数组现在按每个玩家的 team 子数组中的 order 值排序。如果多个玩家的此值相等,这些玩家将按他们的 position 排序。结果数组为:

$players = [
    0 => [
        'name'     => 'Frank',
        'team_id'  => 5,
        'position' => 1,
        'team'     => [
            'id'    => 5,
            'order' => 1,
        ],
    ],
    1 => [
        'name'     => 'Maria',
        'team_id'  => 5,
        'position' => 4,
        'team'     => [
            'id'    => 5,
            'order' => 1,
        ],
    ],
    2 => [
        'name'     => 'John',
        'team_id'  => 2,
        'position' => 3,
        'team'     => [
            'id'    => 1,
            'order' => 2,
        ],
    ],
];

同样,该方法也可以处理对象数组。在上面的示例中,每个 player 可能是数组,而 teams 是对象。该方法将检测每个嵌套级别中元素的类型并相应地处理它。

array_flatten_with_dots(iterable $array[, string $id = '']) array
参数:
  • $array (iterable) -- 要扁平化的多维数组

  • $id (string) -- 可选 ID,用于添加到外部键前。内部用于扁平化键。

返回类型:

array

返回:

扁平化的数组

此函数通过使用点号作为键的分隔符,将多维数组扁平化为单键值数组。

$arrayToFlatten = [
    'personal' => [
        'first_name' => 'john',
        'last_name'  => 'smith',
        'age'        => '26',
        'address'    => 'US',
    ],
    'other_details' => 'marines officer',
];

$flattened = array_flatten_with_dots($arrayToFlatten);

检查后,$flattened 等于:

[
    'personal.first_name' => 'john',
    'personal.last_name'  => 'smith',
    'personal.age'        => '26',
    'personal.address'    => 'US',
    'other_details'       => 'marines officer',
];

用户可以自行使用 $id 参数,但这不是必需的。该函数在内部使用此参数来跟踪扁平化的键。如果用户提供初始 $id,它将添加到所有键前。

// using the same data from above
$flattened = array_flatten_with_dots($arrayToFlatten, 'foo_');
/*
 * $flattened is now:
 * [
 *     'foo_personal.first_name' => 'john',
 *     'foo_personal.last_name'  => 'smith',
 *     'foo_personal.age'        => '26',
 *     'foo_personal.address'    => 'US',
 *     'foo_other_details'       => 'marines officer',
 * ]
 */
array_group_by(array $array, array $indexes[, bool $includeEmpty = false]) array
参数:
  • $array (array) -- 数据行(很可能来自查询结果)

  • $indexes (array) -- 用于分组值的索引。遵循点号语法

  • $includeEmpty (bool) -- 如果为 true,null'' 值不会被过滤掉

返回类型:

array

返回:

按索引值分组的数组

此函数允许你按索引值将数据行分组在一起。返回数组的深度等于作为参数传递的索引数量。

示例显示了一些数据(即从 API 加载的)具有嵌套数组。

$employees = [
    [
        'id'         => 1,
        'first_name' => 'Urbano',
        'gender'     => null,
        'hr'         => [
            'country'    => 'Canada',
            'department' => 'Engineering',
        ],
    ],
    [
        'id'         => 2,
        'first_name' => 'Case',
        'gender'     => 'Male',
        'hr'         => [
            'country'    => null,
            'department' => 'Marketing',
        ],
    ],
    [
        'id'         => 3,
        'first_name' => 'Emera',
        'gender'     => 'Female',
        'hr'         => [
            'country'    => 'France',
            'department' => 'Engineering',
        ],
    ],
    [
        'id'         => 4,
        'first_name' => 'Richy',
        'gender'     => null,
        'hr'         => [
            'country'    => null,
            'department' => 'Sales',
        ],
    ],
    [
        'id'         => 5,
        'first_name' => 'Mandy',
        'gender'     => null,
        'hr'         => [
            'country'    => 'France',
            'department' => 'Sales',
        ],
    ],
    [
        'id'         => 6,
        'first_name' => 'Risa',
        'gender'     => 'Female',
        'hr'         => [
            'country'    => null,
            'department' => 'Engineering',
        ],
    ],
    [
        'id'         => 7,
        'first_name' => 'Alfred',
        'gender'     => 'Male',
        'hr'         => [
            'country'    => 'France',
            'department' => 'Engineering',
        ],
    ],
    [
        'id'         => 8,
        'first_name' => 'Tabby',
        'gender'     => 'Male',
        'hr'         => [
            'country'    => 'France',
            'department' => 'Marketing',
        ],
    ],
    [
        'id'         => 9,
        'first_name' => 'Ario',
        'gender'     => 'Male',
        'hr'         => [
            'country'    => null,
            'department' => 'Sales',
        ],
    ],
    [
        'id'         => 10,
        'first_name' => 'Somerset',
        'gender'     => 'Male',
        'hr'         => [
            'country'    => 'Germany',
            'department' => 'Marketing',
        ],
    ],
];

我们想首先按 gender 分组,然后按 hr.department 分组(最大深度 = 2)。 首先是排除空值时的结果:

$result = array_group_by($employees, ['gender', 'hr.department']);

$result = [
    'Male' => [
        'Marketing' => [
            [
                'id'         => 2,
                'first_name' => 'Case',
                'gender'     => 'Male',
                'hr'         => [
                    'country'    => null,
                    'department' => 'Marketing',
                ],
            ],
            [
                'id'         => 8,
                'first_name' => 'Tabby',
                'gender'     => 'Male',
                'hr'         => [
                    'country'    => 'France',
                    'department' => 'Marketing',
                ],
            ],
            [
                'id'         => 10,
                'first_name' => 'Somerset',
                'gender'     => 'Male',
                'hr'         => [
                    'country'    => 'Germany',
                    'department' => 'Marketing',
                ],
            ],
        ],
        'Engineering' => [
            [
                'id'         => 7,
                'first_name' => 'Alfred',
                'gender'     => 'Male',
                'hr'         => [
                    'country'    => 'France',
                    'department' => 'Engineering',
                ],
            ],
        ],
        'Sales' => [
            [
                'id'         => 9,
                'first_name' => 'Ario',
                'gender'     => 'Male',
                'hr'         => [
                    'country'    => null,
                    'department' => 'Sales',
                ],
            ],
        ],
    ],
    'Female' => [
        'Engineering' => [
            [
                'id'         => 3,
                'first_name' => 'Emera',
                'gender'     => 'Female',
                'hr'         => [
                    'country'    => 'France',
                    'department' => 'Engineering',
                ],
            ],
            [
                'id'         => 6,
                'first_name' => 'Risa',
                'gender'     => 'Female',
                'hr'         => [
                    'country'    => null,
                    'department' => 'Engineering',
                ],
            ],
        ],
    ],
];

这里是相同的代码,但这次我们想包含空值:

$result = array_group_by($employees, ['gender', 'hr.department'], true);

$result = [
    '' => [
        'Engineering' => [
            [
                'id'         => 1,
                'first_name' => 'Urbano',
                'gender'     => null,
                'hr'         => [
                    'country'    => 'Canada',
                    'department' => 'Engineering',
                ],
            ],
        ],
        'Sales' => [
            [
                'id'         => 4,
                'first_name' => 'Richy',
                'gender'     => null,
                'hr'         => [
                    'country'    => null,
                    'department' => 'Sales',
                ],
            ],
            [
                'id'         => 5,
                'first_name' => 'Mandy',
                'gender'     => null,
                'hr'         => [
                    'country'    => 'France',
                    'department' => 'Sales',
                ],
            ],
        ],
    ],
    'Male' => [
        'Marketing' => [
            [
                'id'         => 2,
                'first_name' => 'Case',
                'gender'     => 'Male',
                'hr'         => [
                    'country'    => null,
                    'department' => 'Marketing',
                ],
            ],
            [
                'id'         => 8,
                'first_name' => 'Tabby',
                'gender'     => 'Male',
                'hr'         => [
                    'country'    => 'France',
                    'department' => 'Marketing',
                ],
            ],
            [
                'id'         => 10,
                'first_name' => 'Somerset',
                'gender'     => 'Male',
                'hr'         => [
                    'country'    => 'Germany',
                    'department' => 'Marketing',
                ],
            ],
        ],
        'Engineering' => [
            [
                'id'         => 7,
                'first_name' => 'Alfred',
                'gender'     => 'Male',
                'hr'         => [
                    'country'    => 'France',
                    'department' => 'Engineering',
                ],
            ],
        ],
        'Sales' => [
            [
                'id'         => 9,
                'first_name' => 'Ario',
                'gender'     => 'Male',
                'hr'         => [
                    'country'    => null,
                    'department' => 'Sales',
                ],
            ],
        ],
    ],
    'Female' => [
        'Engineering' => [
            [
                'id'         => 3,
                'first_name' => 'Emera',
                'gender'     => 'Female',
                'hr'         => [
                    'country'    => 'France',
                    'department' => 'Engineering',
                ],
            ],
            [
                'id'         => 6,
                'first_name' => 'Risa',
                'gender'     => 'Female',
                'hr'         => [
                    'country'    => null,
                    'department' => 'Engineering',
                ],
            ],
        ],
    ],
];