고양이 개체의 배열이 있습니다.
$cats = Array
(
[0] => stdClass Object
(
[id] => 15
),
[1] => stdClass Object
(
[id] => 18
),
[2] => stdClass Object
(
[id] => 23
)
)
한 줄에 고양이 ID 배열을 추출하고 싶습니다 (함수도 루프도 아님).
array_walk
with 를 사용 create_function
하려고했지만 어떻게해야할지 모르겠습니다.
어떤 생각?
답변
PHP 5.5 이상이 있는 경우 가장 좋은 방법은 내장 함수를 사용하는 것입니다 array_column()
.
$idCats = array_column($cats, 'id');
하지만 아들은 배열이거나 배열로 변환되어야합니다.
답변
경고
create_function()
는 PHP 7.2.0부터 더 이상 사용되지 않습니다. 이 기능에 의존하는 것은 매우 권장되지 않습니다.
array_map()
기능을 사용할 수 있습니다 .
이렇게해야합니다.
$catIds = array_map(create_function('$o', 'return $o->id;'), $objects);
답변
솔루션은 사용중인 PHP 버전에 따라 다릅니다. 최소한 두 가지 솔루션이 있습니다.
먼저 (최신 PHP 버전)
@JosepAlsina가 전에 말했듯이 가장 짧은 해결책은 array_column
다음과 같이 사용 하는 것입니다.
$catIds = array_column($objects, 'id');
주의 : 질문에 사용 array
된 \stdClass
es를 포함하는
반복은 PHP 버전에서만 가능합니다 >= 7.0
. 그러나 array
포함하는 array
s를 사용하면 PHP부터 동일한 작업을 수행 할 수 있습니다 >= 5.5
.
두 번째 (이전 PHP 버전)
@Greg는 이전 PHP 버전에서 다음을 수행 할 수 있다고 말했습니다.
$catIds = array_map(create_function('$o', 'return $o->id;'), $objects);
그러나주의하십시오 : 최신 PHP 버전에서는 다음과 같이 s >= 5.3.0
를 사용하는 것이 좋습니다 Closure
.
$catIds = array_map(function($o) { return $o->id; }, $objects);
차이점
첫 번째 솔루션은 새로운 기능을 생성하여 RAM에 넣습니다. 가비지 수집기는 어떤 이유로 든 메모리에서 이미 생성되고 이미 호출 된 함수 인스턴스를 삭제하지 않습니다. 그리고 사실에 관계없이 생성 된 함수 인스턴스는 포인터가 없기 때문에 다시 호출 할 수 없습니다. 다음에이 코드를 호출하면 동일한 함수가 다시 생성됩니다. 이 행동은 천천히 당신의 기억을 채 웁니다 …
비교를위한 메모리 출력이있는 두 예 :
나쁜
while (true)
{
$objects = array_map(create_function('$o', 'return $o->id;'), $objects);
echo memory_get_usage() . "\n";
sleep(1);
}
// the output
4235616
4236600
4237560
4238520
...
좋은
while (true)
{
$objects = array_map(function($o) { return $o->id; }, $objects);
echo memory_get_usage() . "\n";
sleep(1);
}
// the output
4235136
4235168
4235168
4235168
...
여기에서도 논의 할 수 있습니다.
메모리 누수?! ‘array_map’내에서 ‘create_function’을 사용할 때 Garbage Collector가 제대로 작동합니까?
답변
function extract_ids($cats){
$res = array();
foreach($cats as $k=>$v) {
$res[]= $v->id;
}
return $res
}
한 줄로 사용하십시오 .
$ids = extract_ids($cats);
답변
암호
<?php
# setup test array.
$cats = array();
$cats[] = (object) array('id' => 15);
$cats[] = (object) array('id' => 18);
$cats[] = (object) array('id' => 23);
function extract_ids($array = array())
{
$ids = array();
foreach ($array as $object) {
$ids[] = $object->id;
}
return $ids;
}
$cat_ids = extract_ids($cats);
var_dump($cats);
var_dump($cat_ids);
?>
산출
# var_dump($cats);
array(3) {
[0]=>
object(stdClass)#1 (1) {
["id"]=>
int(15)
}
[1]=>
object(stdClass)#2 (1) {
["id"]=>
int(18)
}
[2]=>
object(stdClass)#3 (1) {
["id"]=>
int(23)
}
}
# var_dump($cat_ids);
array(3) {
[0]=>
int(15)
[1]=>
int(18)
[2]=>
int(23)
}
나는 루프를 사용하는 것을 알고 있지만 가장 간단한 방법입니다! 그리고 함수를 사용하면 여전히 한 줄로 끝납니다.
답변
우조 케이크로 쉽게 할 수 있습니다
$result = array_map(Functions::extract()->id, $arr);
또는 배열 (ouzo goodies에서)
$result = Arrays::map($arr, Functions::extract()->id);
확인 : http://ouzo.readthedocs.org/en/latest/utils/functions.html#extract
ouzo를 사용한 함수형 프로그래밍도 참조하십시오 (링크를 게시 할 수 없습니다).
답변
경고
create_function()
는 PHP 7.2.0부터 더 이상 사용되지 않습니다. 이 기능에 의존하는 것은 매우 권장되지 않습니다.
PHP의 내장 루프는 해석 된 루프보다 빠르기 때문에 실제로 한 줄로 만드는 것이 좋습니다.
$result = array();
array_walk($cats, create_function('$value, $key, &$result', '$result[] = $value->id;'), $result)