26

この質問は以前に尋ねられたと確信しています。最初に見つけられなかったことをお詫びします。

元の配列:

[0] => Array
    (
        [categoryId] => 1
        [eventId] => 2
        [eventName] => 3
        [vendorName] => 4
    )

[1] => Array
    (
        [categoryId] => 5
        [eventId] => 6
        [eventName] => 7
        [vendorName] => 8
    )

[2] => Array
    (
        [categoryId] => 9
        [eventId] => 10
        [eventName] => 11
        [vendorName] => 12
    )

次の結果を期待しています: print_r(get_values_from_a_key_in_arrays('categoryId', $array));

[0] => 1
[1] => 5
[2] => 9

独自の foreach ベースの関数を作成するよりもクリーンなものを探しています。foreach が答えなら、私はすでにそれを用意しています。

編集:ハードコードされたキーを使用したくありません。ソリューションへの呼び出しの例を示しただけです。ありがとう!^_^

PHP 5.3 のクイック グラブ ソリューション:

private function pluck($key, $data) {
    return array_reduce($data, function($result, $array) use($key) {
        isset($array[$key]) && $result[] = $array[$key];
        return $result;
    }, array());
}
4

8 に答える 8

33

したがって、pluckfiltereachmap 、friendsなどの高階 コレクション/イテレーター関数の優れた点は、それらを組み合わせて、より複雑な一連の操作を構成できることです。

ほとんどの言語はこれらのタイプの関数を提供します(コレクション、イテレーター、列挙/列挙可能などのパッケージを探します)...一部の言語は他の言語よりも多くの関数を提供し、関数の名前は言語間で異なることがよくあります(つまり、collect == map、削減==フォールド)。ご使用の言語に関数が存在しない場合は、存在する関数から関数を作成できます。

テストケースに関しては...array_reduceを使用してpluck実装できます。私が投稿した最初のバージョンは;に依存していました。ただし、このタスクではarray_reduceの方が簡潔であるという@salatheに同意します。array_mapはOKオプションですが、最終的にはさらに多くの作業を行う必要があります。最初は少し奇妙に見えるかもしれませんが、コールバックがきちんと整理されていれば、すべてうまくいきます。array_maparray_reduce

あまりナイーブpluckではない場合も、反復値を「呼び出す」(関数/メソッド)ことができるかどうかを確認します。以下の単純な実装では、構造がハッシュ(連想配列)であると想定しています。

これにより、テストケースデータ(フィクスチャ)がセットアップされます。

<?php

$data[] = array('categoryId' => 1,    'eventId' => 2,  'eventName' => 3,  'vendorName' => 4);
$data[] = array('categoryId' => 5,    'eventId' => 6,  'eventName' => 7,  'vendorName' => 8);
$data[] = array('categoryId' => 9,    'eventId' => 10, 'eventName' => 11, 'vendorName' => 12);
$data[] = array(/* no categoryId */   'eventId' => 10, 'eventName' => 11, 'vendorName' => 12);
$data[] = array('categoryId' => false,'eventId' => 10, 'eventName' => 11, 'vendorName' => 12);
$data[] = array('categoryId' => 0.0,  'eventId' => 10, 'eventName' => 11, 'vendorName' => 12);

好みのプルックのバージョンを選択してください

$preferredPluck = 'pluck_array_reduce'; // or pluck_array_map

PHP 5.3以降の「pluck」:array_reduceは簡潔な実装を提供しますが、array_mapバージョンほど簡単に推論することはできません。

function pluck_array_reduce($key, $data) {
  return array_reduce($data, function($result, $array) use($key){
    isset($array[$key]) &&
      $result[] = $array[$key];

    return $result;
  }, array());
}

PHP 5.3以降の「pluck」:array_mapはこれに完全ではないため、さらにチェックを行う必要があります(それでも、多くの潜在的なケースは考慮されていません)。

function pluck_array_map($key, $data) {
  $map = array_map(function($array) use($key){
    return isset($array[$key]) ? $array[$key] : null;
  }, $data);

  // is_scalar isn't perfect; to make this right for you, you may have to adjust
  return array_filter($map, 'is_scalar');
}

レガシーPHP<5.3の「プル」

従来のcreate_functionを使用することもできます。しかし、それは悪い形であり、推奨されておらず、またまったくエレガントでもないので、私はそれを見せないことにしました。

function pluck_compat($key, $data) {
  $map = array();
  foreach ($data as $array) {
    if (array_key_exists($key, $array)) {
      $map[] = $array[$key];
    }
  }
  unset($array);

  return $map;
}

ここでは、実行しているPHPのバージョンに基づいて呼び出す「pluck」のバージョンを選択します。スクリプト全体を実行すると、使用しているバージョンに関係なく、正しい答えが得られるはずです。

$actual   = version_compare(PHP_VERSION, '5.3.0', '>=')
          ? $preferredPluck('categoryId', $data)
          : pluck_compat('categoryId', $data);
$expected = array(1, 5, 9, false, 0.0);
$variance = count(array_diff($expected, $actual));

var_dump($expected, $actual);
echo PHP_EOL;
echo 'variance: ', $variance, PHP_EOL;

print @assert($variance)
    ? 'Assertion Failed'
    : 'Assertion Passed';

末尾の「?>」がないことに注意してください。それは必要ないからです。そのままにしておくよりも、そのままにしておくほうがよいでしょう。

FWIW、これはarray_columnとしてPHP5.5に追加されているようです。

于 2012-05-18T21:31:38.523 に答える
9

マッピングはあなたが必要とするものです:

$input = array(
    array(
        'categoryId' => 1,
        'eventId' => 2,
        'eventName' => 3,
        'vendorName' => 4,
    ),
    array(
        'categoryId' => 5,
        'eventId' => 6,
        'eventName' => 7,
        'vendorName' => 8,
    ),
    array(
        'categoryId' => 9,
        'eventId' => 10,
        'eventName' => 11,
        'vendorName' => 12,
    ),
);

$result = array_map(function($val){
    return $val['categoryId'];
}, $input);

または、必要な関数を作成します。

function get_values_from_a_key_in_arrays($key, $input){
    return array_map(function($val) use ($key) {
        return $val[$key];
    }, $input);
};

そしてそれを使用します:

$result = get_values_from_a_key_in_arrays('categoryId', $array);

匿名のコールバックが許可されている PHP >= 5.3 で動作します。以前のバージョンでは、以前にコールバックを定義し、無名関数の代わりにその名前を渡す必要があります。

于 2012-05-18T21:24:46.830 に答える
6

これには組み込み関数はありませんが、通常は " pluck " と呼ばれます。

于 2012-05-18T21:19:57.723 に答える
5
<?php
$a = array(
        array('a' => 1, 'b' => 2),
        array('a' => 2, 'b' => 2),
        array('a' => 3, 'b' => 2),
        array('a' => 4, 'b' => 2)
);

function get_a($v) {
        return $v['a'];
}

var_dump(array_map('get_a', $a));

create_function または匿名関数を使用できます (PHP 5.3 >=)

<?php
$a = array(
        array('a' => 1, 'b' => 2),
        array('a' => 2, 'b' => 2),
        array('a' => 3, 'b' => 2),
        array('a' => 4, 'b' => 2)
);

var_dump(array_map(create_function('$v', 'return $v["a"];'), $a));

上記のようにコールバック関数を作成し、それを array_map で使用します。

于 2012-05-18T21:21:52.723 に答える
4

PHP 5.5 以降では、以下を使用しますarray_column

$events = [
    [ 'categoryId' => 1, 'eventId' =>  2, 'eventName' =>  3, 'vendorName' =>  4 ],
    [ 'categoryId' => 5, 'eventId' =>  6, 'eventName' =>  7, 'vendorName' =>  8 ],
    [ 'categoryId' => 9, 'eventId' => 10, 'eventName' => 11, 'vendorName' => 12 ],
];

print_r(array_column($events, 'categoryId'));

3v4l でオンラインでご覧ください。

5.5 より前のバージョンでは、polyfillの使用を検討できます。

于 2016-10-26T14:11:57.257 に答える
3

組み込み関数はありません。でも で簡単に作れarray_map()ます。

$array = array(
    array(
        "categoryID"   => 1,
        "CategoryName" => 2,
        "EventName"    => 3,
        "VendorName"   => 4
    ),
    array(
        "categoryID"   => 5,
        "CategoryName" => 6,
        "EventName"    => 7,
        "VendorName"   => 8
    ),
    array(
        "categoryID"   => 9,
        "CategoryName" => 10,
        "EventName"    => 11,
        "VendorName"   => 12
    )
);

$newArray = array_map(function($el) {
    return $el["categoryID"];
}, $array);

var_dump($newArray);
于 2012-05-18T21:23:58.280 に答える
2

必要なときにLispはどこにありますか? 実際、PHPでは管理も非常に簡単です。以下に示すように、array_map 関数を使用するだけです。

# bunch o data
$data = array();
$data[0] = array("id" => 100, "name" => 'ted');
$data[1] = array("id" => 200, "name" => 'mac');
$data[2] = array("id" => 204, "name" => 'bub');

# what you want to do to each bit of it
function pick($n) { return($n['id']); }
# what you get after you do that
$map = array_map("pick", $data);
# see for yourself
print_r($map);
于 2012-05-18T21:38:10.250 に答える
0

array_filterを使用して、目的のキーに基づいて関数を渡すことができます。

ただし、Tadeckの答えははるかに優れています。

于 2012-05-18T21:22:36.030 に答える