将数组转换为键值数组而不进行迭代

时间:2012-11-21 13:48:57

标签: php

将对象数组映射到键值对象数组的最简单方法是什么,其中key是对象的某些属性?

例如:

class Cartoon
{
  public $title;
  public function __construct($title)
  {
    $this->title = $title;
  }
}

$cartoons = array(new Cartoon('Tom and Jerry'), new Cartoon('Cheburashka'));

$mappedCartoons = array();

foreach ($cartoons as $cartoon)
{
  $mappedCartoons[$cartoon->title] = $cartoon;
}

print_r ($mappedCartoons);

PS。我想知道是否可以处理迭代和额外变量$mappedCartoons

3 个答案:

答案 0 :(得分:4)

您可以使用array_reduce来实现目标。

<?php

$cartoons = array_reduce($cartoons, function($result, $cartoon) {
  $result[$cartoon->title] = $cartoon;
  return $result;
}, array());

?>

这个想法不是我的,在这里找到:http://www.danielauener.com/howto-use-array_map-functionality-on-an-associative-array-changing-keys-and-values/

答案 1 :(得分:0)

如果必须使用基本数组,则只需在创建时键入键:

$cartoons = array(
    'Tom and Jerry' => new Cartoon('Tom and Jerry'), 
    'Cheburashka' => new Cartoon('Cheburashka'),
);

或者,您可以创建实现各种数组/迭代相关接口的容器对象,并可以用作常规数组:

class CartoonArray extends ArrayObject {

    public function __construct($input, $flags = 0, $iterator_class = "ArrayIterator") {
        parent::__construct(array(), $flags, $iterator_class);
        // since the original ArrayObject implemented in C and they don't it won't pick up our overriden ossetSet we have to type it out here explicitly
        foreach ($input as $value) {
            $this->offsetSet(null, $value);
        }
    }

    public function offsetSet($index, $value) {
        parent::offsetSet($value->title, $value);
    }
}

$cartoons = new CartoonArray(array(new Cartoon('Tom and Jerry'), new Cartoon('Cheburashka')));
$cartoons[] = new Cartoon('Sesame street');

print $cartoons['Tom and Jerry']->title;
unset($cartoons['Tom and Jerry']);

foreach ($cartoons as $k => $v) {
    print $k."\n";
}

答案 2 :(得分:0)

我想不出一种不涉及迭代的方法。我可以想到一种不需要额外变量的方法:

$cartoons = array(new Cartoon('Tom and Jerry'), new Cartoon('Cheburashka'));
foreach( $cartoons as $key => $cartoon )
{
    $cartoons[ $cartoon->title ] = $cartoon;
    unset( $cartoons[ $key ] );
}

var_dump( $cartoons );

然而,the documentation of foreach注意到:

  

由于foreach依赖于内部数组指针,因此在循环内更改它可能会导致意外行为。

我不完全确定这也适用于我的例子。也许别人可以在这里说话。

为了安全起见,也许这种替代方案更合适,因为它在迭代之前以$len的初始长度启动$cartoons

$cartoons = array(new Cartoon('Tom and Jerry'), new Cartoon('Cheburashka'));
for( $i = 0, $len = count( $cartoons ); $i < $len; $i++ )
{
    $cartoon = $cartoons[ $i ];
    $cartoons[ $cartoon->title ] = $cartoon;
    unset( $cartoons[ $i ] );
}

var_dump( $cartoons );

此示例假设初始$cartoons具有'正确'的顺序编号键,但从0开始。