PHP : array_map 함수에서 인덱스를 얻을 수 있습니까?


87

다음과 같이 PHP에서지도를 사용하고 있습니다.

function func($v) {
    return $v * 2;
}

$values = array(4, 6, 3);
$mapped = array_map(func, $values);
var_dump($mapped);

함수에서 값의 인덱스를 얻을 수 있습니까?

또한-인덱스가 필요한 코드를 작성하는 경우 맵 대신 for 루프를 사용해야합니까?

답변:


215

물론 할 수 있습니다. array_keys():

function func($v, $k)
{
    // key is now $k
    return $v * 2;
}

$values = array(4, 6, 3);
$mapped = array_map('func', $values, array_keys($values));
var_dump($mapped);

20
멋진 대답은 array_map () ped 메서드에 추가 매개 변수를 전달할 수 있다는 것을 몰랐습니다. 매일 새로운 것을 배우십시오!
GordonM 2011 년

1
@Gordon 예 array_map(), 임의의 수의 인수를 제공 할 수 있습니다. :)
Aron Rotteveel

13
PHP는에서 반환 된 키 array_keys가 원래 배열과 동일한 순서로 유지 된다는 것을 보장하지 않으므로 매우 위험한 접근 방식 입니다. 따라서 키를 잘못된 값에 매핑하게 될 수 있습니다. 안전한 방법은 array_keys의 두 번째 인수 로만 사용한 array_map다음 use문을 사용 하여 배열을 클로저로 전달하는 것입니다.
user487772 2015

12
솔직히 PHP에 콜백의 두 번째 매개 변수로 각 요소의 키를 제공하는 맵 함수가없는 이유를 이해할 수 없습니다.
독감

1
@flu PHP는 이유없이 나쁜 언어라는 제목을 얻지 못했습니다.
xZero

9

익명 배열을 통해 익명 함수를 매핑 할 때 키에 액세스 할 수있는 방법이 없습니다.

array_map(
    function($val) use ($foo) { /* ... */ },
    array(key1 => val1,
          key2 => val2,
          /* ... */));

array_reduce는 키에 대한 액세스 권한도 얻지 못합니다. array_walk는 키에 액세스 할 수 있지만 배열은 참조로 전달되므로 간접 계층이 필요합니다.

일부 솔루션은 다음과 같습니다.

쌍의 배열

원래 배열을 변경하기 때문에 이것은 나쁘다. 또한 상용구 "array ()"호출은 배열 길이에 따라 선형 적으로 증가합니다.

array_map(
    function($pair) use ($foo) {
        list($key, $val) = $pair;
        /* ... */
    },
    array(array(key1, val1),
          array(key2, val2),
          /* ... */));

임시 변수

우리는 원래 배열에서 행동하고 있고 상용구는 일정하지만 기존 변수를 쉽게 제거 할 수 있습니다.

$i_hope_this_does_not_conflict = array(key1 => val1,
                                       key2 => val2,
                                       /* ... */);
array_map(
    function($key, $val) use ($foo) { /* ... */ },
    array_keys($i_hope_this_does_not_conflict),
    $i_hope_this_does_not_conflict);
unset($i_hope_this_does_not_conflict);

원샷 기능

함수 범위를 사용하여 기존 이름을 방해하는 것을 방지 할 수 있지만 "사용"이라는 추가 레이어를 추가해야합니다.

call_user_func(
    function($arr) use ($foo) {
        return array_map(function($key, $val) use ($foo) { /* ... */ },
                         array_keys($arr),
                         $arr);
    },
    array(key1 => val1,
          key2 => val2,
          /* ... */));

다중 인수 원샷 기능

"사용"상용구를 방지하기 위해 원래 범위에서 매핑 할 함수를 정의합니다.

call_user_func(
    function($f, $arr) {
        return array_map($f, array_keys($arr), $arr);
    },
    function($key, $val) use ($foo) { /* ... */ },
    array(key1 => val1,
          key2 => val2,
          /* ... */));

새로운 기능

주목해야 할 흥미로운 점은 마지막 원샷 함수가 멋지고 일반적인 시그니처를 가지고 있고 array_map과 매우 비슷하다는 것입니다. 이 이름을 지정하고 다시 사용할 수 있습니다.

function array_mapk($f, $arr) {
    return array_map($f, array_keys($arr), $arr);
}

애플리케이션 코드는 다음과 같습니다.

array_mapk(
    function($key, $val) use ($foo) { /* ... */ },
    array(key1 => val1,
          key2 => val2,
          /* ... */));

간접 어레이 워크

위의 내용을 작성할 때 참조로 전달되는 인수가 필요하기 때문에 array_walk를 무시했습니다. 그러나 이후 call_user_func를 사용하여이 문제를 해결하는 것이 쉽다는 것을 깨달았습니다. 지금까지 이것이 최고의 버전이라고 생각합니다.

call_user_func(
    'array_walk',
    array(key1 => val1,
          key2 => val2,
          /* ... */),
    function($val, $key) use ($foo) { /* ... */ });

1

매우 간단합니다.

array_map fuction : 인덱스 키가 없습니다!

 $params = [4,6,2,11,20];

 $data = array_map(function($v) { return ":id{$v}";}, $params);

 array (size=5)
  0 => string ':id4' (length=4)
  1 => string ':id6' (length=4)
  2 => string ':id2' (length=4)
  3 => string ':id11' (length=5)
  4 => string ':id20' (length=5)

이제 array_keys와 결합하십시오.

$data = array_map(
    function($k) use ($params) { return ":id{$k}_${params[$k]}"; },
    array_keys($params)
 );

array (size=5)
  0 => string ':id0_4' (length=6)
  1 => string ':id1_6' (length=6)
  2 => string ':id2_2' (length=6)
  3 => string ':id3_11' (length=7)
  4 => string ':id4_20' (length=7)

0

다음을 사용하여 자신 만의지도 기능을 만들 수 있습니다 foreach.

<?php

function myCallback($key, $val)
{
    var_dump("myCallback - key: $key, val: $val");
    return $val * 2;
}

function foreachMap($callback, $givenArray) {
    $result = [];
    foreach ($givenArray as $key=>$val) {
        $result[$key] = $callback($key, $val);
    }
    return $result;
}

$values = array(4, 6, 3);
$mapped = foreachMap('myCallback', $values);
var_dump($mapped);

시도 : https://3v4l.org/pmFlB

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.