web-dev-qa-db-ja.com

PHP-配列内の配列をマージする方法

PHPでn個の配列をマージする方法。私はどのように仕事をすることができますか?
array_merge(from : $result[0], to : $result[count($result)-1])
[〜#〜] or [〜#〜]
array_merge_recursive(from: $result[0], to : $result[count($result) -1])


どこ$resultは、次のように内部に複数の配列がある配列です。

$result = Array(
0 => array(),//associative array
1 => array(),//associative array
2 => array(),//associative array
3 => array()//associative array
)

私の結果は次のとおりです。

$result = Array(
    0 => Array(
        "name" => "Name",
        "events" => 1,
        "types" => 2
    ),
    1 => Array(
        "name" => "Name",
        "events" => 1,
        "types" => 3
    ),
    2 => Array(
        "name" => "Name",
        "events" => 1,
        "types" => 4
    ),
    3 => Array(
        "name" => "Name",
        "events" => 2,
        "types" => 2
    ),
    4 => Array(
        "name" => "Name",
        "events" => 3,
        "types" => 2
    )
)

そして私が必要なのは

$result = Array(
"name" => "name",
"events" => array(1,2,3),
"types" => array(2,3,4)
)
55
Lekhnath

array_merge は可変数の引数を取ることができるため、少し call_user_func_array トリックを使用して$result配列を渡すことができます。

$merged = call_user_func_array('array_merge', $result);

これは基本的に、次のように入力した場合のように実行されます。

$merged = array_merge($result[0], $result[1], .... $result[n]);

更新:

5.6では、配列を引数にアンパックするための ...演算子 があるため、次のことができます。

$merged = array_merge(...$result);

そして、同じ結果が得られます。 *

*パックされていない配列に整数キーがある限り、同じ結果になります。そうしないと、E_RECOVERABLE_ERROR : type 4096 -- Cannot unpack array with string keysエラーが発生します。

156
complex857

よろしければ:

  • array_mergeに入る各パラメーターが実際に配列であることを確認します
  • マージする配列の1つに特定のプロパティを指定します

この機能を使用できます:

_function mergeArrayofArrays($array, $property = null)
{
    return array_reduce(
        (array) $array, // make sure this is an array too, or array_reduce is mad.
        function($carry, $item) use ($property) {

            $mergeOnProperty = (!$property) ?
                    $item :
                    (is_array($item) ? $item[$property] : $item->$property);

            return is_array($mergeOnProperty)
                ? array_merge($carry, $mergeOnProperty)
                : $carry;
    }, array()); // start the carry with empty array
}
_

実際の動作を見てみましょう。ここにいくつかのデータがあります。

単純な構造:マージする配列の純粋な配列。

_$peopleByTypesSimple = [
    'teachers' => [
            0  => (object) ['name' => 'Ms. Jo', 'hair_color' => 'brown'],
            1  => (object) ['name' => 'Mr. Bob', 'hair_color' => 'red'],
    ],

    'students' => [
            0  => (object) ['name' => 'Joey', 'hair_color' => 'blonde'],
            1  => (object) ['name' => 'Anna', 'hair_color' => 'Strawberry Blonde'],
    ],

    'parents' => [
            0  => (object) ['name' => 'Mr. Howard', 'hair_color' => 'black'],
            1  => (object) ['name' => 'Ms. Wendle', 'hair_color' => 'Auburn'],
    ],
];
_

それほど単純ではない:配列の配列ですが、peopleおよびignorecountを指定したい。

_$peopleByTypes = [
    'teachers' => [
        'count' => 2,
        'people' => [
            0  => (object) ['name' => 'Ms. Jo', 'hair_color' => 'brown'],
            1  => (object) ['name' => 'Mr. Bob', 'hair_color' => 'red'],
        ]
    ],

    'students' => [
        'count' => 2,
        'people' => [
            0  => (object) ['name' => 'Joey', 'hair_color' => 'blonde'],
            1  => (object) ['name' => 'Anna', 'hair_color' => 'Strawberry Blonde'],
        ]
    ],

    'parents' => [
        'count' => 2,
        'people' => [
            0  => (object) ['name' => 'Mr. Howard', 'hair_color' => 'black'],
            1  => (object) ['name' => 'Ms. Wendle', 'hair_color' => 'Auburn'],
        ]
    ],
];
_

それを実行します

_$peopleSimple = mergeArrayofArrays($peopleByTypesSimple);
$people = mergeArrayofArrays($peopleByTypes, 'people');
_

結果-両方ともこれを返します:

_Array
(
    [0] => stdClass Object
        (
            [name] => Ms. Jo
            [hair_color] => brown
        )

    [1] => stdClass Object
        (
            [name] => Mr. Bob
            [hair_color] => red
        )

    [2] => stdClass Object
        (
            [name] => Joey
            [hair_color] => blonde
        )

    [3] => stdClass Object
        (
            [name] => Anna
            [hair_color] => Strawberry Blonde
        )

    [4] => stdClass Object
        (
            [name] => Mr. Howard
            [hair_color] => black
        )

    [5] => stdClass Object
        (
            [name] => Ms. Wendle
            [hair_color] => Auburn
        )

)
_

特別な楽しみ配列の人々オブジェクト(または関連配列)からの「名前」のように、配列またはオブジェクトの1つのプロパティを選び出したい場合は、この機能

_function getSinglePropFromCollection($propName, $collection, $getter = true)
{
    return (empty($collection)) ? [] : array_map(function($item) use ($propName) {
        return is_array($item) 
            ? $item[$propName] 
            : ($getter) 
                ? $item->{'get' . ucwords($propName)}()
                : $item->{$propName}
    }, $collection);
}
_

ゲッターは、場合によっては保護/プライベートオブジェクト用です。

$namesOnly = getSinglePropFromCollection('name', $peopleResults, false);

返す

_Array
(
    [0] => Ms. Jo
    [1] => Mr. Bob
    [2] => Joey
    [3] => Anna
    [4] => Mr. Howard
    [5] => Ms. Wendle
)
_
4
amurrell

Complex857からの回答は本当に気に入りましたが、配列に保存する必要がある数値キーがあったため、うまくいきませんでした。

+演算子を使用してキーを保持し( 数値キーを使用したPHP array_merge で推奨)、array_reduceを使用して配列をマージしました。

したがって、数値キーを保持しながら配列内の配列をマージする場合は、次のように実行できます。

<?php
$a = [
    [0 => 'Test 1'],
    [0 => 'Test 2', 2 => 'foo'],
    [1 => 'Bar'],
];    

print_r(array_reduce($a, function ($carry, $item) { return $carry + $item; }, []));
?>

結果:

Array
(
    [0] => Test 1
    [2] => foo
    [1] => Bar
)
3
Friedrich

これを試して

$result = array_merge($array1, $array2);

または、array_mergeの代わりに、結合を実行する+ opを使用できます。

$array2 + array_fill_keys($array1, '');
0
Jayram