12

我在一个看起来像这样的类中有一个方法;

class SomeClass {
    private $hidden = array(....);

    /**
     * @return array - numeric indexed array in order of $this->hidden.
     * Suitable for use by list(var1, var2, ...)
     */
    public function getAsList($list = array())
    {
       return array_values(array_intersect_key($this->hidden, array_flip($list) );
    }

但这没有用,因为方法的调用者不知道实例变量 $hidden 中关联数组中键/元素对的顺序。理想情况下,返回的数组与 $list 中指定的键的顺序完全相同。例如:

$foo = new SomeClass();
list($foo, $bar, $baz) = $foo->getAsList(array('foo', 'bar', 'baz');

我可以轻松地在循环中编写一些明确的、冗长的 PHP 代码来执行此操作,但是是否有一些巧妙的方法来使用各种数组函数,例如 array_multisort() 以最少的代码行将其吐出(希望在编译的代码中)速度——我会测试它,如果它重要的话)。

从某种意义上说,这是一个我还不知道答案的脑筋急转弯。我在没有明确循环的情况下这样做并不重要,但我很好奇它是否可以完成。我花了 30 分钟左右的时间,还没有找到解决方案。

4

2 回答 2

16

也许array_replace是您的难题中缺少的部分:

public function getAsList($list = array())
{
  $klist = array_flip($list);
  return array_values(array_intersect_key(array_replace($klist, $this->hidden), $klist));
}

示例(演示):

$hidden = [
  'apples' => 19,
  'eggs' => 7,
  'grapes' => 144,
  'mushrooms' => 3,
  'oranges' => 16
];

$list = ['grapes', 'apples', 'eggs', 'oranges'];

$klist = array_flip($list);
print_r(array_values(array_intersect_key(array_replace($klist, $hidden), $klist)));

/*
Array
(
    [0] => 144
    [1] => 19
    [2] => 7
    [3] => 16
)
*/
于 2013-07-03T01:09:20.090 回答
1

这是函数式编程在可读性、可维护性和效率方面与语言结构相比相形见绌的情况之一。

我对函数式编程有偏见,但在这种情况下,它只是没有回报。

代码:(演示

$hidden = [
  'apples' => 19,
  'eggs' => 7,
  'grapes' => 144,
  'mushrooms' => 3,
  'oranges' => 16
];

$list = ['grapes', 'apples', 'eggs', 'oranges'];
foreach ($list as $item) {
    if (isset($hidden[$item])) {
        $result[] = $hidden[$item];
    }
}

var_export($result);

输出:

array (
  0 => 144,
  1 => 19,
  2 => 7,
  3 => 16,
)

如果您坚持使用函数式编程,那么按以下顺序执行所需的操作将是最有效的:

  • 过滤数组
  • 对过滤后的数组的键进行排序
  • 重新索引有序的过滤数组

方法如下:

代码:(演示

$flippedList = array_flip($list);
var_export(array_values(array_replace($flippedList, array_intersect_key($hidden, $flippedList))));

(与上一个片段相同的输出)

从逻辑上讲,对其中包含多余元素的数组进行排序是没有意义的。首先减轻负担。

于 2019-07-19T13:05:33.530 回答