[php] PHP-객체 배열에서 속성 추출

고양이 개체의 배열이 있습니다.

$cats = Array
    (
        [0] => stdClass Object
            (
                [id] => 15
            ),
        [1] => stdClass Object
            (
                [id] => 18
            ),
        [2] => stdClass Object
            (
                [id] => 23
            )
)

한 줄에 고양이 ID 배열을 추출하고 싶습니다 (함수도 루프도 아님).

array_walkwith 를 사용 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\stdClasses를 포함하는
반복은 PHP 버전에서만 가능합니다 >= 7.0. 그러나 array포함하는 arrays를 사용하면 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)