5.8.28 버전에서 Support/Collection::
, Support/Collection::replcace()
Support/Collection::
메소드가 추가됐다.
mergeRecursive()
는 주어진 배열이나 컬렉션을 기존의 컬렉션과 합친다. 기존의 merge()
는 같은 문자열 키가 있으면 덮어썼는데, mergeRecursive()
는 같은 문자열 키의 값을 배열로 만든다.
$collection = collect(['product_id' => 1, 'price' => 100]);
$merged = $collection->mergeRecursive(['product_id' => 2, 'price' => 200, 'discount' => false]);
$merged->all();
// ['product_id' => [1, 2], 'price' => [100, 200], 'discount' => false]
PHP의 array_merge_recursive
기능을 컬렉션에 추가한 것이라고 하니 array_merge_recursive
에 익숙치 않은 사람은 다음의 array_merge_recursive 설명도 참고하자.
array_merge_recursive
는 하나 이상의 배열을 재귀적으로 합치는 기능이다. array_merge
는 최상위 레벨 인덱스를 기준으로 합치고, 같은 인덱스가 있으면 덮어쓴다. 반면 array_merge_recursive
는 더 낮은 수준의 인덱스까지 처리해준다.
$a = [
'server' => [
'php' => 7.3
],
'database' => 'mysql'
];
$b = [
'server' => [
'node.js' => [9, 10]
]
];
$array_merge_result = array_merge($a, $b);
// ['server' => ['node.js' => [9, 10]], 'database' => 'mysql']
$array_merge_recursive_result = array_merge_recursive($a, $b);
// ['server' => ['php' => 7.3, 'node.js' => [9, 10]], 'database' => 'mysql']
replace()
는 merge()
와 비슷하지만, 문자열 키 뿐만 아니라 숫자 인덱스도 지원한다.
$collection = collect(['Taylor', 'Abigail', 'James']);
$replaced = $collection->replace([1 => 'Victoria', 3 => 'Finn']);
$replaced->all();
// ['Taylor', 'Victoria', 'James', 'Finn']
replaceRecursive()
도 mergeRecursive()
와 마찬가지로 다차원 배열을 재귀적으로 처리해준다.
$collection = collect(['Taylor', 'Abigail', ['James', 'Victoria', 'Finn']]);
$replaced = $collection->replaceRecursive(['Charlie', 2 => [1 => 'King']]);
// $replaced = $collection->replace(['Charlie', 2 => [1 => 'King']]);
$replaced->all();
// ['Charlie', 'Abigail', ['James', 'King', 'Finn']]
replaceRecursive
대신 replace
로 해보면 아래와 같이 다른 결과가 나온다.
$collection = collect(['Taylor', 'Abigail', ['James', 'Victoria', 'Finn']]);
// $replaced = $collection->replaceRecursive(['Charlie', 2 => [1 => 'King']]);
$replaced = $collection->replace(['Charlie', 2 => [1 => 'King']]);
$replaced->all();
// ['Charlie', 'Abigail', ['King']]
컬렉션에 새로 추가된 replace()
와 replaceRecursive()
도 PHP의 array_replace
와 array_replace_recursive
를 컬렉션 메소드로 구현한 것이다.
php.net의 예제를 보면 둘의 동작과 차이가 쉽게 이해가 될 것이다.
$base = ['citrus' => ["orange"] , 'berries' => ["blackberry", "raspberry"]];
$replacements = ['citrus' => ['pineapple'], 'berries' => ['blueberry']];
$basket = array_replace_recursive($base, $replacements);
print_r($basket);
$basket = array_replace($base, $replacements);
print_r($basket);
위 코드의 출력
Array
(
[citrus] => Array
(
[0] => pineapple
)
[berries] => Array
(
[0] => blueberry
[1] => raspberry
)
)
Array
(
[citrus] => Array
(
[0] => pineapple
)
[berries] => Array
(
[0] => blueberry
)
)
PR을 보니 이미 같은 내용의 PR이 있었고 거절 당했었다. 혹시 코드가 이번 PR에 비해 구려서 채택이 안됐나 싶어 코드를 비교해봤는데, 완전히 같은 코드여서 의아했다. 지난번 PR을 리뷰했던 사람은 replace
대신 map
을 활용할 것을 권유했었는데, 이번 PR을 제출한 사람은 map
은 재귀적인 처리할 때는 오히려 문제가 될 수 있다고 댓글을 추가했다. 짐작컨데, 이전 PR 때는 리뷰어의 의견을 받아들여 거절했지만, 나중에 생각이 바뀐게 아닌가 싶다. 만약 그런거라면 같은 내용의 코드로 먼저 PR 했던 사람이 약간 억울할 수 있을 것 같다.
===
1일 1식 라라벨
2019년 7월 11일
메쉬 코리아 개발자. 바쁜 팀장님 대신 알려주는 신입 PHP 개발자 안내서를 쓰고, 클린 아키텍처 인 PHP를 번역했습니다. 처음부터 제대로 배우는 라라벨(Laravel Up & Running 2nd Edition)을 번역했습니다.