programing

'array_keys()'를 호출하지 않고 array_map()로 1단계 키 액세스

telebox 2023. 5. 22. 20:57
반응형

'array_keys()'를 호출하지 않고 array_map()로 1단계 키 액세스

다음과 같은 방법이 있습니까?

$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)
    )
);

하지만 전화하는 대신에array_keys그리고.array_values$test_array변수?

원하는 출력은 다음과 같습니다.

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

array_map은 키를 처리하지 않기 때문에 사용할 수 없습니다.

array_walk는 다음을 수행합니다.

$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"
// }

그러나 매개 변수로 지정된 배열을 변경하므로 정확하게 기능하는 프로그래밍이 아닙니다(질문에 그렇게 태그가 지정된 경우).또한 설명에서 지적한 대로 배열 값만 변경되므로 키가 질문에서 지정한 값이 아닙니다.

원하는 경우 다음과 같이 자신의 위에 있는 점을 수정하는 기능을 작성할 수 있습니다.

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"
// }

이것이 아마도 가장 짧고 쉽게 추론할 수 있는 방법일 것입니다.

$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')
)

다음은 매우 간단한 PHP 5.5 호환 솔루션입니다.

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

으로 두 의 값,사자가제호자두체가개값가을합배반니다야환해열을 .return [key, value]따라서 에 대한 내부 호출은 배열 배열을 생성합니다.그러면 에 의해 다시 1차원 배열로 변환됩니다.

사용.

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

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

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

산출량

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

부분적용

다른 배열이지만 동일한 매핑 기능으로 이 기능을 여러 번 사용해야 하는 경우, 호출 시에만 데이터 배열을 전달할 수 있는 부분 함수 응용 프로그램('커리링' 관련)을 수행할 수 있습니다.

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));

주어진 조건에서 동일한 출력을 생성합니다.$func그리고.$ordinals앞에서 말한 것과 같습니다.

참고: 매핑된 함수가 두 개의 서로 다른 입력에 대해 동일한 키를 반환하는 경우, 이후 키와 연결된 값이 승리합니다.의 입력 배열 및 출력 결과를 반대로 합니다.array_map_assoc이전 키가 승리할 수 있도록 합니다. (이 예에서 반환된 키는 소스 배열의 키를 통합하므로 충돌할 수 없습니다. 즉, 고유해야 합니다.)


대안

다음은 위의 변형으로, 일부에서는 더 논리적이지만 PHP 5.6이 필요합니다.

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

이 변형에서는 제공된 함수(데이터 배열이 매핑된 함수)가 대신 하나의 행, 즉, 연관 배열을 반환해야 합니다.return [key => value]그런 다음, 통화 가능한 통화를 매핑한 결과를 간단히 압축 해제하고 다음으로 전달합니다.array_merge이전과 마찬가지로 중복 키를 반환하면 나중에 값이 승리합니다.

n.b를 사용한다고 했습니다. Alex83690은 코멘트에서 다음과 같이 언급했습니다.array_replace서 신대여 에.array_merge정수 키를 보존합니다. array_replace는 입력 배열을 수정하지 않으므로 기능 코드에 대해 안전합니다.

만약 당신이 PHP 5.3에서 5.5를 사용한다면, 다음과 같습니다.그것은 사용합니다.array_reduce " 이수진"+array 연산자는 키를 유지하면서 결과 2차원 배열을 1차원 배열로 변환합니다.

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;
    }, []);
}

사용.

이 두 가지 변형은 다음과 같이 사용됩니다.

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

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

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

에 하십시오.=>,$func.

출력은 이전과 동일하며, 각각 이전과 동일한 방식으로 부분적으로 적용할 수 있습니다.


요약

원래 질문의 목표는 호출되는 더 복잡한 함수를 사용하지 않고 가능한 한 간단하게 호출을 실행하는 것입니다. 특히 키와 값을 분할하지 않고 단일 인수로 데이터 배열을 전달할 수 있는 기능이 필요합니다.이 답변의 시작 부분에 제공된 기능을 사용합니다.

$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)));

또는 이 질문에 대해서만 다음과 같이 단순화할 수 있습니다.array_map_assoc()출력 키를 묻는 질문이 없으므로 출력 키를 삭제하는 함수:

$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));

그래서 대답은 아니오입니다. 전화하는 것을 피할 수 없습니다.array_keys가 있는 곳을 추상화할 수 있습니다.array_keys고차 함수로 호출됩니다. 이 정도면 충분할 수 있습니다.

$array = [
  'category1' => 'first category',
  'category2' => 'second category',
];
 
$new = array_map(function($key, $value) {
  return "{$key} => {$value}";
}, array_keys($array), $array);

PHP 5.3 이상의 경우:

$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)
    )
);

버전 5.6 이상을 사용하여 문제에 대한 다른 해결책을 추가하겠습니다.이미 제공된 우수한 솔루션보다 더 효율적인지는 모르겠지만(아마 그렇지 않을 것입니다), 저는 다음과 같이 읽기가 더 간단합니다.

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

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

용사를 합니다.strval()array_map다음을 생성합니다.

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

바라건대 이것을 이해하기가 꽤 쉽다고 생각하는 사람이 저 혼자만은 아니길 바랍니다. array_combine를 생성합니다.key => value키 배열과 값 배열의 배열, 나머지는 꽤 자기 설명적입니다.

이것 봐!사소한 해결책이 있습니다!

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

처럼, 질에언급바같이와된문,,array_map 에는 이미 필요한 기능이 있습니다.여기에 있는 다른 답변들은 심각하게 복잡합니다.array_walk작동하지 않습니다.

사용.

예에서 예상하는 바와 같습니다.

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

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

"수동 루프"는 다음을 사용하는 사용자 정의 함수를 작성하는 것을 의미합니다.foreach " 과같새배반환니다합을열은다음▁like다"와 새 이 반환됩니다.array_map함수의 범위가 원인이 되기 때문입니다.$array참조가 아닌 사본이 될 것:

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

다을사용술기는하를 사용하는 .array_map와 함께array_keys하지만 실제로는 더 단순해 보이고 사용할 수 있기 때문에 더 강력합니다.null쌍을 으로: ""-" "다음과 같이 입력합니다."

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

이것이 제 프로젝트에서 제가 이것을 구현한 방법입니다.

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));
}

한 번만 필요하면 닫을 수 있습니다.발전기가 필요합니다.

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

$x_result = (function(array $arr) {
    foreach ($arr as $key => $value) {
        yield "$key loves $value";
    }
})($test_array);

var_dump(iterator_to_array($x_result));

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

재사용 가능한 경우:

function xmap(callable $cb, array $arr)
{
    foreach ($arr as $key => $value) {
        yield $cb($key, $value);
    }
}

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

eis의 답변을 바탕으로 원래 어레이를 엉망으로 만들지 않기 위해 다음과 같이 했습니다.

$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);

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;
}

예:

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

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

출력:

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

물론, 당신은 사용할 수 있습니다.array_values정확히 OP가 원하는 것을 반환합니다.

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

YaLinqo 라이브러리*는 이러한 작업에 적합합니다..NET의 LINQ 포트로 모든 콜백에서 값과 키를 완벽하게 지원하며 SQL과 유사합니다.예:

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

아니면 그냥:

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

여기서,'"$k loves $v"'이 라이브러리에서 지원하는 전체 폐쇄 구문의 바로 가기입니다. toArray()결국은 선택 사항입니다..foreach,toArray호출을 제거할 수 있습니다.

내가 개발한

저는 항상 배열 지도의 자바스크립트 변형을 좋아합니다.가장 간단한 버전은 다음과 같습니다.

/**
 * @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;
}

이제 콜백 함수를 전달하여 값을 구성하는 방법을 확인할 수 있습니다.

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

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

저는 다음과 같은 일을 할 것입니다.

<?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",
)));

?>

결과:

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

어레이 라이브러리의 맵 방법을 사용하면 원하는 것을 다음과 같이 쉽게 얻을 수 있습니다.

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

또한 키를 보존하고 새 배열을 반환하며, 필요에 따라 몇 가지 다른 모드도 제공합니다.

키를 보존하지 않고 이 작업을 수행하는 또 다른 방법:

$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)
);

명백한 답을 놓치고 있는 것 같습니다.

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;
}

array_map과 똑같이 작동합니다.거의.

사실, 순지않습다니하수▁pure않▁actually.map당신이 다른 언어들로부터 알고 있듯이.에 매우 기능이 는 정확하게 php를 풀고 싶지 않기 입니다.worse is better접근.

정말, 사실은 그렇지 않습니다.map하지만 유용합니다.하지만, 그것은 여전히 매우 유용합니다.

  • 분명한 중 이 array_map의 입니다.each()모든 입력 배열에서 값만 사용할 수 있습니다.한 번에 더 많은 어레이를 반복할 수 있습니다.

  • 번째 후 입니다. 은 두번째차키콜반서후환처방다니입식는리되된에백은입니다. 콜백 함수에서 반환된 값은 다음과 같아야 합니다.array('new_key', 'new_value')키를 변경할 수도 있고 변경할 수도 있으며, 동일한 키가 반환된 경우 이전 값을 덮어쓸 수도 있습니다.은 흔한 일이 .map하지만 키를 다시 쓸 수 있습니다.

  • 세 번째 이상한 것은, 만약 당신이 생략한다면.key▁(▁by)▁in의해▁()로array(1 => 'value')또는array(null, 'value') , , , 와새됩니다.$array[] = $value사용되었습니다.그렇지 않습니다.map일반적인 행동이기도 하지만 가끔은 도움이 되는 것 같아요

  • 네 번째 이상한 것은 콜백 함수가 값을 반환하지 않거나 반환하는 경우입니다.null출력에서 현재 키와 값의 전체 집합이 생략되며, 단순히 건너뜁니다.이 기능은 완전히 사용할 수 없습니다.map은 이 을 py에 대한 스턴트 을 만들 입니다, 하만그것이기훌륭한스더턴만것다입들니블로트지을능은▁py▁for▁excellent.array_filter_assoc만약 그런 기능이 있었다면.

  • 요소를 에는 다음 요소를 생략합니다.1 => ...) (가치 부분) 콜백의 반환에서,null실제 값 대신 사용됩니다.

  • 가 한 기타 0그리고.1콜백의 반환은 무시됩니다.

  • 가 그고마 로으람을 한 나머지 을 반환하는 null생략된 또는배열키값와모생처것다같리로다습음니과므되처럼된략두은.

    1. 요소에 대한 새 키가 할당되었습니다.
    2. null값으로 됩니다.
경고:
이 마지막 기능은 이전 기능의 잔재일 뿐이며 아마도 완전히 쓸모가 없을 것입니다.이 기능은 무작위로 사용되므로 이 기능에 의존하는 것은 매우 권장되지 않습니다. 이상 사용되지 않으며 이후 릴리스에서 예기치 않게 변경되었습니다.

예:
에서와는 달리array_map 변수가 전된 어매변수에 되었습니다.array_map_assoc첫 번째 콜백 매개 변수를 제외하고는 어레이에 자동으로 캐스트됩니다.

예: 예:
// TODO: examples, anyone?

언급URL : https://stackoverflow.com/questions/13036160/access-first-level-keys-with-array-map-without-calling-array-keys

반응형