PHP:如何创建一个好的foreach简写?

3
我有一个像这样的简单对象(或数组)...
stdClass Object (
[people] => Array
(
    [0] => stdClass Object (
        [name] => 'John',
        [age] => 50,
    )

    [0] => stdClass Object (
        [name] => 'Martin',
        [age] => 47,
    )
)

我可以使用foreach轻松地循环遍历它,代码如下:
foreach ($people as $person) {
    echo $person->name . '<br>';
}

但我希望有一种更简洁的方法像这样回显所有名称...

print_each($people->name)

只需要一行短小的代码,它就可以像我的三行foreach代码一样完成相同的工作。

是否有类似的函数或者我们该如何创建这样一个函数呢?


1
为什么?可读性永远不应被低估。如果必须这样做,请编写一个函数/方法。 - DevDonkey
为了测试/调试目的。如何编写这样的函数? - Martin Zeltin
将foreach放在一个函数中? - DevDonkey
7个回答

6
您可以使用array_column和implode函数。
echo implode("<br>\n", array_column($arr, "name"));

5

也许 array_map 是最接近你想要的。

array_map(function($person) { echo $person->name; }, $people);

函数还是太长了,能不能写一个更短的函数? - Martin Zeltin
4
当然可以!那么这段代码如何翻译呢:array_map(function($p) { echo $p->name; }, $people); ;-)注:该段代码为 PHP 代码,作用是将 $people 数组中的每个元素传入 function() 函数并执行,最终输出每个元素的 name 属性。 - Don't Panic

4
最简单,也不那么丑的方法是向Person对象添加一个__toString方法,如下所示:
class Person {
    public $name;

    public function __toString()
    {
        return (string) $this->name;
    }
}

这样,您就可以使用非常简短的代码:

来实现此功能。
array_walk($people, 'printf');

语法。


1
看起来在这种情况下它们只是StdClass对象,但总的来说我认为这是一个好主意! - Don't Panic

2
如果您有一个数组,您可以使用array_column函数来处理它:
$people = [
    ['name' => 'John', 'age' => 3],
    ['name' => 'Carl', 'age' => 43]
];

var_dump(
    array_column($people, 'name') 
);

 /*
array(2) {
  [0]=>
  string(4) "John"
  [1]=>
  string(4) "Carl"
}

很好,但仅适用于数组而不是对象。 - Martin Zeltin
@MartinZeltin array_column适用于对象数组,除非您仍在使用PHP 5。 - Don't Panic
这正是我所需要的。 - keroles Monsef

2
PHP 7.4 版本起,您可以执行以下操作:
echo implode('', array_map(fn($person) => $person->name . '<br>', $people));
  1. 内部的array_map()函数将第二个参数设置为初始数组$people
  2. 内部的array_map()函数将第一个参数设置为箭头函数fn() =>,该函数从初始数组$people中获取单个项目$person
  3. 在箭头函数内部,每个$person->name都会与'<br>'连接起来,并作为值写入新数组中。
  4. 此新数组将由array_map()函数返回。
  5. 该数组的项目将作为implode()函数的第二个参数传递,并使用空字符串''粘合在一起。
  6. implode()返回的整个字符串将被echo输出。

1
如果你想更“智能”地编写程序,可以写出类似这样的代码:
 array_walk_recursive($a, function($v, $k) {echo $k === 'name' ? $v : '';});

但是,聪明取代易读性,这总是一个坏主意。


0
如果我必须编写一个函数来完成这个任务,它大概会是以下的样子:
function print_each($collection, $property) {
  foreach ($collection as $item) {
    echo $item->$property . "<br />";
  }
}

可以这样使用:

$people = [
  (object)[
    "name" => "Bob",
    "age" => 25
  ],
  (object)[
    "name" => "Dan",
    "age" => 31
  ],
  (object)[
    "name" => "Sally",
    "age" => 45
  ]
];

print_each($people, "name"); // prints "Bob<br />Dan<br />Sally<br />"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接