18

私は、コールバックがキーと値の両方を割り当てることができるperlのmap()関数に慣れているため、入力がフラット配列である連想配列を作成します。辞書スタイルのハッシュを作成するだけの場合に役立つことはわかってarray_fill_keys()いますが、必ずしもすべての値を同じにする必要がない場合はどうでしょうか。明らかに、すべてのことはforeach反復で実行できますが、他にどのような(おそらくよりエレガントな)方法が存在しますか?

編集:変換を明確にするための例を追加します。変換にこだわる必要はありません。問題は、フラットリストをハッシュに変換することです。この場合、すべての値が同じになるとは限りません。

$original_array: ('a', 'b', 'c', 'd')
$new_hash: ('a'=>'yes', 'b'=>'no', 'c'=>'yes', 'd'=>'no')

*note: the values in this example are arbitrary, governed by some business logic that is not really relevant to this question. For example, perhaps it's based on the even-oddness of the ordinal value of the key

実際の例 ここで提供された回答を使用して、$ _ POSTを解析して、特定の基準に一致する入力フィールドのみのリストを取得する方法を次に示します。これは、たとえば、フォームに多数の入力フィールドがあるが、それらの特定のグループを一緒に処理する必要がある場合に役立ちます。

この場合、データベースへのマッピングを表すいくつかの入力フィールドがあります。各入力フィールドは次のようになります。 <input name="field-user_email" value="2" />このタイプの各フィールドには、接頭辞「field-」が付いています。

まず、実際に「field-」で始まる入力フィールドのみのリストを取得し、次に$mapped_fields、抽出されたフィールド名をキーとして、実際の入力フィールドの値を持つと呼ばれる連想配列を作成します。値として。

$mapped_fields = array_reduce( preg_grep( '/field-.+/', array_keys( $_POST ) ), function( $hash, $field ){ $hash[substr( $field, 6 )] = $_POST[$field]; return $hash; } );

どの出力:

Array ( [date_of_birth] => 1 [user_email] => 2 [last_name] => 3 [first_name] => 4 [current_position] => 6 )

(したがって、否定論者を未然に防ぐために、このコンパクトなコードは、$ _ POSTを繰り返し処理し、キーごとにプレフィックスがあるかどうかを確認する単純なループよりも、おそらくはるかに読みにくいことに同意します。したがって、それとその値を配列にポップします)

4

4 に答える 4

46

私は数日前にまったく同じ問題を抱えていました。を使用することはできませんarray_maparray_reduce、トリックを行います。

$arr = array('a','b','c','d');
$assoc_arr = array_reduce($arr, function ($result, $item) {
    $result[$item] = (($item == 'a') || ($item == 'c')) ? 'yes' : 'no';
    return $result;
}, array());
var_dump($assoc_arr);

結果:

array(4) { ["a"]=> string(3) "yes" ["b"]=> string(2) "no" ["c"]=> string(3) "yes" ["d"]=> string(2) "no" }

于 2012-11-19T20:53:51.547 に答える
2

これは、受け入れられた方法での私のコメントの説明です。うまくいけば読みやすくなります。これはWordPressクラスからのものであるため、データを書き込むための$wpdb参照は次のようになります。

class SLPlus_Locations {
    private $dbFields = array('name','address','city');

    public function MakePersistent() {
        global $wpdb;
        $dataArray = array_reduce($this->dbFields,array($this,'mapPropertyToField'));
        $wpdb->insert('wp_store_locator',$dataArray);
    }

    private function mapPropertyToField($result,$property) {
        $result[$property] = $this->$property;
        return $result;
    }
}

明らかに、完全なソリューションにはもう少しありますが、array_reduce()に関連する部分があります。foreachや、array_map()とカスタム挿入ステートメントを使用して問題を強制するよりも読みやすくエレガントです。

良い!

于 2013-03-08T21:29:22.593 に答える
2

私の知る限り、1つの式では完全に不可能なので、foreachループを使用することもできます。

$new_hash = array();

foreach($original_array as $item) {
    $new_hash[$item] = 'something';
}

1つの式で必要な場合は、先に進んで関数を作成します。

function array_map_keys($callback, $array) {
    $result = array();

    foreach($array as $item) {
        $r = $callback($item);

        $result[$r[0]] = $r[1];
    }

    return $result;
}
于 2012-07-19T18:09:15.553 に答える
1

yieldオペレーターの良いユースケース!

$arr = array('a','b','c','d');

$fct = function(array $items) {
            foreach($items as $letter)
            {
                yield sprintf("key-%s",
                    $letter
                ) => "yes";
            }
        };

$newArr = iterator_to_array($fct($arr));

これは次のようになります。

array(4) {
  'key-a' =>
  string(3) "yes"
  'key-b' =>
  string(3) "yes"
  'key-c' =>
  string(3) "yes"
  'key-d' =>
  string(3) "yes"
}
于 2019-04-24T12:52:28.330 に答える