Mảng_map của PHP bao gồm các khóa


207

Có cách nào để làm một cái gì đó như thế này:

$test_array = array("first_key" => "first_value", 
                    "second_key" => "second_value");

var_dump(array_map(function($a, $b) { return "$a loves $b"; }, 
         array_keys($test_array), 
         array_values($test_array)));

Nhưng thay vì gọi array_keysarray_values, trực tiếp vượt qua $test_arraybiến?

Đầu ra mong muốn là:

array(2) {
  [0]=>
  string(27) "first_key loves first_value"
  [1]=>
  string(29) "second_key loves second_value"
}

Xem thêm: stackoverflow.com/search?q=each_with_index để biết cách tiếp cận tương phản với vấn đề chung này
dreftymac

Câu trả lời:


204

Không phải với mảng_map, vì nó không xử lý các khóa.

mảng_walk nào:

$test_array = array("first_key" => "first_value",
                    "second_key" => "second_value");
array_walk($test_array, function(&$a, $b) { $a = "$b loves $a"; });
var_dump($test_array);

// array(2) {
//   ["first_key"]=>
//   string(27) "first_key loves first_value"
//   ["second_key"]=>
//   string(29) "second_key loves second_value"
// }

Tuy nhiên, nó thay đổi mảng được cung cấp dưới dạng tham số, do đó, nó không chính xác là lập trình chức năng (vì bạn có câu hỏi được gắn thẻ như vậy). Ngoài ra, như được chỉ ra trong bình luận, điều này sẽ chỉ thay đổi các giá trị của mảng, vì vậy các khóa sẽ không phải là những gì bạn đã chỉ định trong câu hỏi.

Bạn có thể viết một hàm sửa các điểm phía trên nếu bạn muốn, như thế này:

function mymapper($arrayparam, $valuecallback) {
  $resultarr = array();
  foreach ($arrayparam as $key => $value) {
    $resultarr[] = $valuecallback($key, $value);
  }
  return $resultarr;
}

$test_array = array("first_key" => "first_value",
                    "second_key" => "second_value");
$new_array = mymapper($test_array, function($a, $b) { return "$a loves $b"; });
var_dump($new_array);

// array(2) {
//   [0]=>
//   string(27) "first_key loves first_value"
//   [1]=>
//   string(29) "second_key loves second_value"
// }

Ngoại trừ trong trường hợp này, bạn muốn $a = "$b loves $a", khớp với đầu ra mong muốn của OP.
cmbuckley

1
đúng, đã thay đổi :) thật tuyệt khi họ tạo ra Array_map khác với Array_walk.
eis

Tốt đẹp, cảm ơn. Để tránh làm hỏng mảng ban đầu, đây là những gì tôi đã làm (xem câu trả lời của tôi bên dưới)
Jose Tomás Tocino

3
Đây không phải là "lập trình chức năng" mặc dù vì array_walk()không trả về mảng kết quả, mà thay vào đó là một bool.
mae

@mae, vâng, như tôi đã viết trong câu trả lời - thay vì trả về giá trị, nó thay đổi tham số
eis

145

Đây có lẽ là lý do ngắn nhất và dễ nhất để:

$states = array('az' => 'Arizona', 'al' => 'Alabama');

array_map(function ($short, $long) {
    return array(
        'short' => $short,
        'long'  => $long
    );
}, array_keys($states), $states);

// produces:
array(
     array('short' => 'az', 'long' => 'Arizona'), 
     array('short' => 'al', 'long' => 'Alabama')
)

15
Tôi chỉ nhận ra rằng câu hỏi cụ thể nói không sử dụng array_keys(). Điều đó có vẻ như một yêu cầu ngớ ngẩn, mặc dù.
Kevin Beal

3
Câu hỏi cung cấp một giải pháp sử dụng Array_keys (), sẽ thật ngớ ngẩn khi cung cấp một câu trả lời không có lợi thế (ví dụ: gọi ít chức năng hơn) so với giải pháp hiện tại.
Chinoto Vokro

Câu trả lời cho câu hỏi ban đầu là KHÔNG, và đây là giải pháp phù hợp nhất.
usoban

65

Đây là giải pháp tương thích PHP 5.5 rất đơn giản của tôi:

function array_map_assoc(callable $f, array $a) {
    return array_column(array_map($f, array_keys($a), $a), 1, 0);
}

Có thể gọi được mà bạn cung cấp sẽ trả về một mảng có hai giá trị, nghĩa là return [key, value]. array_mapDo đó, cuộc gọi bên trong để tạo ra một mảng các mảng. Điều này sau đó được chuyển đổi trở lại một mảng một chiều bằng array_column.

Sử dụng

$ordinals = [
    'first' => '1st',
    'second' => '2nd',
    'third' => '3rd',
];

$func = function ($k, $v) {
    return ['new ' . $k, 'new ' . $v];
};

var_dump(array_map_assoc($func, $ordinals));

Đầu ra

array(3) {
  ["new first"]=>
  string(7) "new 1st"
  ["new second"]=>
  string(7) "new 2nd"
  ["new third"]=>
  string(7) "new 3rd"
}

Ứng dụng một phần

Trong trường hợp bạn cần sử dụng hàm nhiều lần với các mảng khác nhau nhưng cùng một hàm ánh xạ, bạn có thể thực hiện một thứ gọi là ứng dụng hàm một phần (liên quan đến ' currying '), cho phép bạn chỉ truyền vào mảng dữ liệu khi gọi:

function array_map_assoc_partial(callable $f) {
    return function (array $a) use ($f) {
        return array_column(array_map($f, array_keys($a), $a), 1, 0);
    };
}

...
$my_mapping = array_map_assoc_partial($func);
var_dump($my_mapping($ordinals));

Mà tạo ra cùng một đầu ra, được đưa ra $func$ordinalsnhư trước đó.

LƯU Ý: nếu chức năng được ánh xạ của bạn trả về cùng một khóa cho hai đầu vào khác nhau, giá trị được liên kết với khóa sau sẽ giành chiến thắng. Đảo ngược mảng đầu vào và kết quả đầu ra của array_map_assocđể cho phép các khóa trước đó giành chiến thắng. (Các khóa được trả về trong ví dụ của tôi không thể va chạm vì chúng kết hợp khóa của mảng nguồn, lần lượt phải là duy nhất.)


Thay thế

Sau đây là một biến thể của những điều trên, có thể chứng minh logic hơn đối với một số người, nhưng yêu cầu PHP 5.6:

function array_map_assoc(callable $f, array $a) {
    return array_merge(...array_map($f, array_keys($a), $a));
}

Trong biến thể này, hàm được cung cấp của bạn (qua đó mảng dữ liệu được ánh xạ) thay vào đó sẽ trả về một mảng kết hợp với một hàng, tức là return [key => value]. Kết quả của ánh xạ có thể gọi được sau đó chỉ đơn giản là giải nén và chuyển đến array_merge. Như trước đó, trả lại một khóa trùng lặp sẽ dẫn đến chiến thắng giá trị sau này.

nb Alex83690 đã lưu ý trong một nhận xét rằng sử dụng array_replaceở đây thay cho việc array_mergebảo tồn các khóa nguyên. array_replacekhông sửa đổi mảng đầu vào, vì vậy an toàn cho mã chức năng.

Nếu bạn đang dùng PHP 5.3 đến 5.5, thì sau đây là tương đương. Nó sử dụng array_reduce+toán tử mảng nhị phân để chuyển đổi mảng hai chiều kết quả thành mảng một chiều trong khi bảo quản các khóa:

function array_map_assoc(callable $f, array $a) {
    return array_reduce(array_map($f, array_keys($a), $a), function (array $acc, array $a) {
        return $acc + $a;
    }, []);
}

Sử dụng

Cả hai biến thể này sẽ được sử dụng như vậy:

$ordinals = [
    'first' => '1st',
    'second' => '2nd',
    'third' => '3rd',
];

$func = function ($k, $v) {
    return ['new ' . $k => 'new ' . $v];
};

var_dump(array_map_assoc($func, $ordinals));

Lưu ý =>thay vì ,trong $func.

Đầu ra giống như trước đây và mỗi cái có thể được áp dụng một phần theo cùng một cách như trước đây.


 Tóm lược

Mục tiêu của câu hỏi ban đầu là làm cho việc gọi cuộc gọi trở nên đơn giản nhất có thể, với chi phí có một chức năng phức tạp hơn được gọi; đặc biệt, để có khả năng truyền mảng dữ liệu dưới dạng một đối số, mà không cần tách các khóa và giá trị. Sử dụng chức năng được cung cấp khi bắt đầu câu trả lời này:

$test_array = ["first_key" => "first_value",
               "second_key" => "second_value"];

$array_map_assoc = function (callable $f, array $a) {
    return array_column(array_map($f, array_keys($a), $a), 1, 0);
};

$f = function ($key, $value) {
    return [$key, $key . ' loves ' . $value];
};

var_dump(array_values($array_map_assoc($f, $test_array)));

Hoặc, chỉ cho câu hỏi này, chúng tôi có thể đơn giản hóa array_map_assoc()chức năng bỏ các phím đầu ra, vì câu hỏi không yêu cầu chúng:

$test_array = ["first_key" => "first_value",
               "second_key" => "second_value"];

$array_map_assoc = function (callable $f, array $a) {
    return array_map($f, array_keys($a), $a);
};

$f = function ($key, $value) {
    return $key . ' loves ' . $value;
};

var_dump($array_map_assoc($f, $test_array));

Vì vậy, câu trả lời là KHÔNG , bạn không thể tránh gọi array_keys, nhưng bạn có thể trừu tượng ra nơi array_keysđược gọi vào hàm bậc cao hơn, có thể đủ tốt.


7
Có vẻ như điều này nên được đánh dấu là câu trả lời chính xác.
eddiewould

6
Cảm ơn @eddiewould, nhưng tôi đã trễ khoảng 4 năm rưỡi rồi :) Tôi đến đây để tìm giải pháp, không tìm thấy bất kỳ thứ gì tôi thích, vì vậy đã tự mình tìm ra.
Nicholas Shanks

1
Tôi sẽ là người đó. PHP 5.3 không còn là một yêu cầu cho ngày của câu trả lời này . IMHO.
Erutan409

1
Giải pháp thay thế đầu tiên của bạn không hợp lệ. bạn phải thay thế array_mergebằng array_replaceđể bảo vệ các khóa sẽ là số nguyên.
Alex83690

1
@ Alex83690 Cảm ơn! Mặc dù tôi nói "không hợp lệ" là hơi sai lệch - thật tốt nếu bạn không có bất kỳ khóa số nguyên nào (như trong trường hợp của riêng tôi).
Nicholas Shanks

20

Với PHP5.3 trở lên:

$test_array = array("first_key" => "first_value", 
                    "second_key" => "second_value");

var_dump(
    array_map(
        function($key) use ($test_array) { return "$key loves ${test_array[$key]}"; },
        array_keys($test_array)
    )
);

1
Tôi nghĩ rằng yêu cầu là "thay vì gọi Array_keys và Array_values, trực tiếp truyền biến $ test_array", điều này có thể được sử dụng mà không có Array_keys không?
eis

4

Đây là cách tôi đã thực hiện điều này trong dự án của tôi.

function array_map_associative(callable $callback, $array) {
    /* map original array keys, and call $callable with $key and value of $key from original array. */
    return array_map(function($key) use ($callback, $array){
        return $callback($key, $array[$key]);
    }, array_keys($array));
}

Rất sạch sẽ và không làm thay đổi mảng ban đầu!
Raffaele Candeliere

4

Nhìn đây! Có một giải pháp tầm thường!

function array_map2(callable $f, array $a)
{
    return array_map($f, array_keys($a), $a);
}

Như đã nêu trong câu hỏi, array_map đã có chính xác các chức năng cần thiết . Các câu trả lời khác ở đây thực sự quá phức tạp mọi thứ: array_walkkhông hoạt động.

Sử dụng

Chính xác như bạn mong đợi từ ví dụ của bạn:

$test_array = array("first_key" => "first_value", 
                    "second_key" => "second_value");

var_dump(array_map2(function($a, $b) { return "$a loves $b"; }, $test_array));

các câu trả lời khác quá phức tạp vì câu hỏi được chỉ định qrrqy_keys()không nên được sử dụng cho #reasons
Brad Kent

2

Bằng "vòng lặp thủ công" tôi có nghĩa là viết một hàm tùy chỉnh sử dụng foreach. Điều này trả về một mảng mới giống như array_mapvì phạm vi của hàm gây ra $arraymột bản sao không phải là một tham chiếu:

function map($array, callable $fn) {
  foreach ($array as $k => &$v) $v = call_user_func($fn, $k, $v);
  return $array;
}

Kỹ thuật của bạn sử dụng array_mapvới array_keysnhưng thật ra có vẻ đơn giản và mạnh mẽ hơn bởi vì bạn có thể sử dụng nullnhư một callback để trả lại cặp khóa-giá trị:

function map($array, callable $fn = null) {
  return array_map($fn, array_keys($array), $array);
}

mảng lặp với tham chiếu, có thể gây ra những điều ma quái xảy ra
janenz00

Nó không ma quái, nó chỉ có nghĩa là bạn đã quên unset( $value )bởi vì nó vẫn tồn tại trong phạm vi được xác định.
aziz trừng phạt

@azis, đã đùa về sự ma quái, tham khảo bài viết. Nó sẽ tạo ra hiệu ứng bất ngờ nếu bạn quên không đặt.
janenz00

1
Cảm ơn câu trả lời, nhưng tôi nghĩ khá rõ ràng rằng tôi không muốn sử dụng một vòng lặp truyền thống.
Jose Tomás Tocino

@ janenz00 Xem câu trả lời được chỉnh sửa để làm rõ. Tôi có nghĩa là lặp trong một phạm vi biến sạch.
ryanve

1

Dựa trên câu trả lời của eis , đây là những gì tôi cuối cùng đã làm để tránh làm hỏng mảng ban đầu:

$test_array = array("first_key" => "first_value",
                    "second_key" => "second_value");

$result_array = array();
array_walk($test_array, 
           function($a, $b) use (&$result_array) 
           { $result_array[] = "$b loves $a"; }, 
           $result_array);
var_dump($result_array);

2
Tại sao điều này dễ dàng hơn là chỉ truyền trực tiếp các giá trị mảng và khóa vào mảng_map? Nó chậm hơn và phức tạp hơn, tôi không thấy lợi thế.
Ariel

1
@Ariel bạn có thể sao lưu tuyên bố rằng nó sẽ chậm hơn, ngay cả với số lượng lớn? Nó chỉ cần lặp lại mảng một lần, vì vậy tôi nghĩ nó nên có cường độ nhanh hơn trong ký hiệu O lớn. Tôi đồng ý về sự phức tạp mặc dù.
eis

@eis Nó chậm hơn vì nó tạo ra mảng kết quả cùng một lúc trong PHP, thay vì en masse trong C. Nó không tránh được lệnh gọi Array_keys (mặc dù đó là nhanh vì nó ở C). Điểm chuẩn nó - xem cái nào nhanh hơn, tôi không thực sự chắc chắn, nhưng thường là nhiều mã hơn = mã chậm hơn. Mặc dù phức tạp, điều đó chắc chắn tồi tệ hơn và điều đó quan trọng hơn tốc độ hầu hết thời gian.
Ariel

1
Bạn không cần phải gửi đối số thứ ba tới array_walkvì bạn không tham chiếu nó trong bao đóng.
Steven Lu

1

Tôi đã thực hiện chức năng này, dựa trên câu trả lời của eis :

function array_map_($callback, $arr) {
    if (!is_callable($callback))
        return $arr;

    $result = array_walk($arr, function(&$value, $key) use ($callback) {
        $value = call_user_func($callback, $key, $value);
    });

    if (!$result)
        return false;

    return $arr;
}

Thí dụ:

$test_array = array("first_key" => "first_value", 
                "second_key" => "second_value");

var_dump(array_map_(function($key, $value){
    return $key . " loves " . $value;
}, $arr));

Đầu ra:

array (
  'first_key' => 'first_key loves first_value,
  'second_key' => 'second_key loves second_value',
)

Dĩ nhiên, bạn có thể sử dụng array_valuesđể trả về chính xác những gì OP muốn.

array_values(array_map_(function($key, $value){
    return $key . " loves " . $value;
}, $test_array))

@KevinBeal Tôi sử dụng chức năng này rất nhiều trong công việc của tôi. Bạn có thể chỉ ra lỗi ở đâu?
Julio Vedovatto

2
Đầu tiên, mã đứng đó thiếu một kiểm tra $arrthuộc kiểu mảng, tuy nhiên nếu bạn gõ gợi ý các đối số của bạn callablearraythay vào đó bạn có thể bỏ kiểm tra is_callable. Tiếp theo, bạn thực hiện gán cho giá trị $ mà sau đó không được sử dụng. Bạn chỉ nên bỏ qua giá trị trả lại. Thứ ba, sẽ tốt hơn nếu ném một ngoại lệ trong cuộc gọi lại hơn là trả về false. Sau đó, bạn sẽ luôn trả về một giá trị hợp lệ hoặc luôn luôn ném.
Nicholas Shanks

1

Thư viện YaLinqo * rất phù hợp cho loại nhiệm vụ này. Đó là một cổng LINQ từ .NET, hỗ trợ đầy đủ các giá trị và khóa trong tất cả các cuộc gọi lại và giống với SQL. Ví dụ:

$mapped_array = from($test_array)
    ->select(function ($v, $k) { return "$k loves $v"; })
    ->toArray();

hoặc chỉ:

$mapped_iterator = from($test_array)->select('"$k loves $v"');

Đây '"$k loves $v"'là một lối tắt cho cú pháp đóng hoàn toàn mà thư viện này hỗ trợ. toArray()cuối cùng là tùy chọn. Chuỗi phương thức trả về một trình vòng lặp, vì vậy nếu kết quả chỉ cần lặp đi lặp lại bằng cách sử dụng foreach, toArraycuộc gọi có thể bị xóa.

* được phát triển bởi tôi


1

Tôi sẽ làm một cái gì đó như thế này:

<?php

/**
 * array_map_kv()
 *   An array mapping function to map with both keys and values.
 *
 * @param $callback callable
 *   A callback function($key, $value) for mapping values.
 * @param $array array
 *   An array for mapping.
 */
function array_map_kv(callable $callback, array $array) {
  return array_map(
    function ($key) use ($callback, $array) {
      return $callback($key, $array[$key]); // $callback($key, $value)
    },
    array_keys($array)
  );
}

// use it
var_dump(array_map_kv(function ($key, $value) {
  return "{$key} loves {$value}";
}, array(
  "first_key" => "first_value",
  "second_key" => "second_value",
)));

?>

Các kết quả:

array(2) {
  [0]=>
  string(27) "first_key loves first_value"
  [1]=>
  string(29) "second_key loves second_value"
}

1

Tôi sẽ thêm một giải pháp khác cho vấn đề bằng phiên bản 5.6 trở lên. Không biết nó có hiệu quả hơn các giải pháp tuyệt vời (có thể không), nhưng với tôi nó đơn giản hơn để đọc:

$myArray = [
    "key0" => 0,
    "key1" => 1,
    "key2" => 2
];

array_combine(
    array_keys($myArray),
    array_map(
        function ($intVal) {
            return strval($intVal);
        },
        $myArray
    )
);

Sử dụng strval()như một hàm ví dụ trong array_map, điều này sẽ tạo ra:

array(3) {
  ["key0"]=>
  string(1) "0"
  ["key1"]=>
  string(1) "1"
  ["key2"]=>
  string(1) "2"
}

Hy vọng tôi không phải là người duy nhất thấy điều này khá đơn giản để nắm bắt. array_combinetạo một key => valuemảng từ một mảng các khóa và một mảng các giá trị, phần còn lại là khá tự giải thích.


1

Bạn có thể sử dụng phương pháp bản đồ từ thư viện mảng này để đạt được chính xác những gì bạn muốn một cách dễ dàng như:

Arr::map($test_array, function($a, $b) { return "$a loves $b"; });

Ngoài ra, nó bảo tồn các khóa và trả về mảng mới, chưa kể một vài chế độ khác nhau để phù hợp với nhu cầu của bạn.


1
$array = [
  'category1' => 'first category',
  'category2' => 'second category',
];

$new = array_map(function($key, $value) {
  return "{$key} => {$value}";
}, array_keys($array), $array);

Nguồn


0

Tôi luôn thích các biến thể javascript của bản đồ mảng. Phiên bản đơn giản nhất của nó sẽ là:

/**
 * @param  array    $array
 * @param  callable $callback
 * @return array
 */
function arrayMap(array $array, callable $callback)
{
    $newArray = [];

    foreach( $array as $key => $value )
    {
        $newArray[] = call_user_func($callback, $value, $key, $array);
    }

    return $newArray;
}

Vì vậy, bây giờ bạn có thể chỉ cần truyền cho nó một hàm gọi lại làm thế nào để xây dựng các giá trị.

$testArray = [
    "first_key" => "first_value", 
    "second_key" => "second_value"
];

var_dump(
    arrayMap($testArray, function($value, $key) {
        return $key . ' loves ' . $value;
    });
);

Sẽ hữu ích hơn khi lấy dữ liệu làm đối số cuối cùng cho bất kỳ chức năng nào bạn viết, khi đó bạn có thể tạo một hàm mới thực hiện một số cuộc gọi lại (hành vi) cụ thể - tức là bạn có được thành phần chức năng: h(g(f($data)))áp dụng f, sau đó g, sau đó hcho dữ liệu. Nhìn chung, nó được coi là linh hoạt hơn trong lập trình chức năng để có một chức năng thực hiện cùng một hoạt động trên dữ liệu thợ lặn, hơn là có một chức năng áp dụng các chức năng của thợ lặn cho một tập dữ liệu cố định.
Nicholas Shanks

Trong ví dụ của bạn, bạn chỉ có 1 đối số cho hàm. Tôi thấy dễ dàng hơn khi đặt dữ liệu làm đối số đầu tiên, như mảng_filter, mảng_reduce và các hàm mảng trong javascript.
blablabla

Đó là quan điểm của tôi! Bằng cách truyền dữ liệu lần cuối, nó cho phép bạn cuộn chức năng (tạo một hàm mới kết hợp vòng lặp với thao tác cụ thể) và áp dụng điều đó cho dữ liệu bằng cách gọi hàm mới với một tham số duy nhất. Hiệu trưởng này được giải thích tốt hơn tôi có thể ở đây, trong câu trả lời này: stackoverflow.com/a/5863222
Nicholas Shanks

Việc sử dụng hàm soạn thảo trong một ngôn ngữ như PHP không phải là giải pháp tốt hơn cho vấn đề này?
blablabla

1
Đây là một giải pháp thay thế nhưng đòi hỏi đầu tư nhiều hơn vào FP, ví dụ: github.com/nickshanks/fp-php-talk/blob/master/lib.php#L24 hoặc này: github.com/nickshanks/php-fp/blob /master/src/fp.php#L62
Nicholas Shanks

0

Một cách khác để làm điều này với (bảo quản) các phím:

$test_array = [
    "first_key"     => "first_value",
    "second_key"    => "second_value"
];

$f = function($ar) {
    return array_map(
        function($key, $val) {
            return "{$key} - {$val}";
        },
        array_keys($ar),
        $ar
    );
};

#-- WITHOUT preserving keys
$res = $f($test_array);

#-- WITH preserving keys
$res = array_combine(
    array_keys($test_array),
    $f($test_array)
);

-2

Tôi thấy nó thiếu câu trả lời rõ ràng:

function array_map_assoc(){
    if(func_num_args() < 2) throw new \BadFuncionCallException('Missing parameters');

    $args = func_get_args();
    $callback = $args[0];

    if(!is_callable($callback)) throw new \InvalidArgumentException('First parameter musst be callable');

    $arrays = array_slice($args, 1);

    array_walk($arrays, function(&$a){
        $a = (array)$a;
        reset($a);
    });

    $results = array();
    $max_length = max(array_map('count', $arrays));

    $arrays = array_map(function($pole) use ($max_length){
        return array_pad($pole, $max_length, null);
    }, $arrays);

    for($i=0; $i < $max_length; $i++){
        $elements = array();
        foreach($arrays as &$v){
            $elements[] = each($v);
        }
        unset($v);

        $out = call_user_func_array($callback, $elements);

        if($out === null) continue;

        $val = isset($out[1]) ? $out[1] : null;

        if(isset($out[0])){
            $results[$out[0]] = $val;
        }else{
            $results[] = $val;
        }
    }

    return $results;
}

Hoạt động chính xác như mảng_map. Hầu hết.

Trên thực tế, nó không thuần túy mapnhư bạn biết từ các ngôn ngữ khác. Php rất kỳ lạ, vì vậy nó đòi hỏi một số chức năng người dùng rất kỳ lạ, vì chúng tôi không muốn phá vỡ worse is bettercách tiếp cận bị phá vỡ chính xác của mình .

Thực sự, nó không thực sự mapở tất cả. Tuy nhiên, nó vẫn rất hữu ích.

  • Sự khác biệt rõ ràng đầu tiên từ mảng_map, là hàm gọi lại lấy đầu ra each()từ mọi mảng đầu vào thay vì chỉ có giá trị. Bạn vẫn có thể lặp qua nhiều mảng hơn cùng một lúc.

  • Sự khác biệt thứ hai là cách xử lý khóa sau khi nó được trả về từ cuộc gọi lại; giá trị trả về từ hàm gọi lại phải là array('new_key', 'new_value'). Các khóa có thể và sẽ được thay đổi, các khóa tương tự thậm chí có thể khiến giá trị trước đó bị ghi đè, nếu cùng một khóa được trả về. Đây không phải là maphành vi phổ biến , nhưng nó cho phép bạn viết lại các khóa.

  • Điều kỳ lạ thứ ba là, nếu bạn bỏ qua keygiá trị trả về (bằng array(1 => 'value')hoặc hoặc array(null, 'value')), khóa mới sẽ được gán, như thể $array[] = $valueđược sử dụng. Đó cũng không phải maplà hành vi phổ biến, nhưng đôi khi nó cũng có ích, tôi đoán vậy.

  • Điều kỳ lạ thứ tư là, nếu chức năng gọi lại không trả về giá trị hoặc trả về null, toàn bộ tập hợp các khóa và giá trị hiện tại bị bỏ qua khỏi đầu ra, đơn giản là nó bị bỏ qua. Tính năng này hoàn toàn không phải là mappy, nhưng nó sẽ làm cho chức năng này trở nên tuyệt vời gấp đôi array_filter_assoc, nếu có chức năng như vậy.

  • Nếu bạn bỏ qua phần tử thứ hai ( 1 => ...) (phần giá trị ) trong phần trả về của hàm gọi lại, nullsẽ được sử dụng thay cho giá trị thực.

  • Bất kỳ yếu tố nào khác ngoại trừ những yếu tố có khóa 01trong phần gọi lại đều bị bỏ qua.

  • Và cuối cùng, nếu lambda trả về bất kỳ giá trị nào ngoại trừ nullhoặc mảng, thì nó được xử lý như thể cả khóa và giá trị đều bị bỏ qua, vì vậy:

    1. khóa mới cho phần tử được gán
    2. null được sử dụng như giá trị của nó
CẢNH BÁO:
Hãy nhớ rằng tính năng cuối cùng này chỉ là phần dư của các tính năng trước đó và nó có thể hoàn toàn vô dụng. Dựa vào tính năng này rất không được khuyến khích, vì tính năng này sẽ bị phản đối ngẫu nhiên và thay đổi bất ngờ trong các phiên bản tương lai.

GHI CHÚ:
Không giống như trong array_map, tất cả các tham số không phải là mảng được truyền đến array_map_assoc, ngoại trừ tham số gọi lại đầu tiên, đều được truyền âm thầm vào mảng.

VÍ DỤ:
// TODO: examples, anyone?

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.