【问题标题】:Array declaration comparity数组声明比较
【发布时间】:2013-06-09 16:09:45
【问题描述】:

我目前正在清理一些讨厌的代码。这段代码非常深入地为现有数组定义了几个新键:

$form['long_key_name_right_here_you_see']['title'] = 'Hello';
$form['long_key_name_right_here_you_see']['body'] = 'This be a greeting';
$form['long_key_name_right_here_you_see']['etc'] = 'This does nothing';
$form['another_long_key_name_right']['title'] = 'Hello!';
$form['another_long_key_name_right']['body'] = 'This be a greeting!';
$form['another_long_key_name_right']['etc'] = 'This does nothing.';

我更愿意这样定义:

$arr_form = array('long_key_name_right_here_you_see' => array('title' => 'Hello',
                                                              'body'  => 'This be a greeting',
                                                              'etc'   => 'This does nothing'
),
                  'another_long_key_name_right'      => array('title' => 'Hello!',
                                                              'body'  => 'This be a greeting!',
                                                              'etc'   => 'This does nothing.'));

$form = ($arr_form + $form);
  • 我能否始终依靠我喜欢的方法来获得与现有案例相同的结果?
  • 我喜欢的方法是否会被认为不明确且毫无意义?

基本上,我只是觉得在代码中定义成行的相同键的巨大墙壁看起来有点难看,但也许这只是我的挑剔的想法。

Relevant PHP Documentaion

+ 运算符返回附加到左侧的右侧数组 大批;对于两个数组中都存在的键,来自 将使用左侧数组,并且匹配元素来自 右侧数组将被忽略。

注意:

接受的答案在我的案例中帮助了我。这个问题不一定有一个正确的答案,但可能会启发其他人,就像我一样。

【问题讨论】:

  • 除了语法关闭(你想要$form += $defaultValues)之外,这是要走的路。
  • 你确定这是正确的方法吗?该数组具有现有值,并且需要覆盖键。请检查我在问题中链接的文档并分享您的想法。
  • 啊,是的,我错过了。在这种情况下,您的语法是正确的。我宁愿使用$form = array_merge($form, $defaultValues) 来让读者非常清楚应该 覆盖值(这是+array_merge 之间的区别),但最终结果是一样的。
  • 执行乔恩所说的。试试$form = array_merge($form, $arr_form);,没问题,比联合算子稳定。

标签: php arrays


【解决方案1】:

由于我们使用的是单个数组单元格,我可能会使用指向长键的短指针来提高可读性。就个人而言,我不喜欢过度使用 array() 函数调用,因为它有点难以阅读。

指针不会像临时变量那样占用额外的内存空间。

所以这个:

$form['long_key_name_right_here_you_see']['title'] = 'Hello';
$form['long_key_name_right_here_you_see']['body'] = 'This be a greeting';
$form['long_key_name_right_here_you_see']['etc'] = 'This does nothing';

会变成这样:

$target_form =& $form['long_key_name_right_here_you_see'];

$target_form = array(); // In case it's undefined. Drop this if it's not empty.
$target_form['title'] = 'Hello';
$target_form['body'] = 'This be a greeting';
$target_form['etc'] = 'This does nothing';

unset($target_form); 

请注意,unset 语句将取消设置指针引用,而不是数组的内容。如果您决定稍后重用$target_form,则只需避免覆盖您的数据。

这可能比单纯的评论更值得关注: 小心指针。除非小心使用,否则很容易覆盖数据,很难调试。

【讨论】:

  • 哇,这种方法看起来很漂亮!总是很高兴学习新的代码样式。我会尝试并相应地接受。
  • @RobinCastlin 它可能看起来不错,但您应该始终小心指针。确保您知道自己在做什么,否则调试意外覆盖将困扰您的噩梦。 :)
  • 指针/引用非常适合使代码更简单、更易读,只需确保为它们提供有意义的名称并避免覆盖它们(没有充分的理由)。
  • 感谢您的警告 :) 可以帮助我的美发师而不是我自己的手来处理我的头发。
【解决方案2】:

$arr_form += $form; 不会给你你想要的输出.. 你应该反转变量而不是例子:

$form = array();
$arr_form = array(
        'title' => 'Hello',
        'body' => 'This be a greeting',
        'etc' => 'This does nothing'
);
$form['long_key_name_right_here_you_see'] = $arr_form;
var_dump($form);

【讨论】:

  • 如果我正确阅读了文档,$form += $arr_form 不会覆盖相同的键。
  • 你为什么还要设置$arr_form变量呢?即使我们根本不需要它,它也会留在内存中。
  • 如果你总是想以最小的开销让你override,那么只需分配密钥
  • @h2ooooooo 它们是子模块的配置可以独立工作或与主配置组合的情况,甚至 $form 可以是会话变量
  • 在我的例子中,我只是发现定义一次长键名而不是像这种情况下定义三次更有吸引力。我怀疑这种做法会导致性能损失值得注意。答案已经更新了一点。不过,您的答案在第一个示例中毫无疑问地有效。
【解决方案3】:

每个人的口味不同,语言(PHP、Python等)一般都允许你做同样的事情 以各种方式,服务于所有口味和风格代码......


with 声明理念

@MaximKumpan 的回答就像使用 Python 和其他语言的with..as statement想象一下这样的事情,

   //if not exist, $form['long_key_name_right_here_you_see']=array();    
   with $form['long_key_name_right_here_you_see'] as $f {
     $f['title'] = 'Hello';
     $f['body'] = 'This be a greeting';
     $f['etc'] = 'This does nothing';
   }

注意:想象一下(!),真正的 PHP 代码是 $f =& $form['...'],以 unset($f) 结尾,作为 Max 的代码。

一般配置问题/解决方案

你的问题让我想起了我们之前在各种配置脚本中看到的东西。 这里我们有一个typical example of Mediawiki,提供两种造型风格,两种口味:

$w = array( 'png', 'jpg', 'jp2', 'webp', '...'); // original

$w[] = 'pdf';  // "add one by one item" taste
$w[] = '...';

$new = array( 'pdf', 'ppt', 'jp2' );
$w   = array_merge( $w, $new );  // "add all itens" taste

你还记得另一种方式

$w = $w + $new;
// CAUTION: array_merge, "+" and "+=" are not exactly the same thing!

但是,你的问题不是合并通用数组,它是关于“合并关联数组”...你也可以这样做(!),see this other similar question/answer (另见array_merge_recursive function)。

对于您的示例,array_merge 也是一个有效且可读的解决方案(在您的代码中替换 $arr_form + $form):

 $form = array_merge($form, $arr_form); // not the same as (arr_form,$form)!

Mediawiki(以上链接)是“最佳实践”的一个示例,并且(我也)更喜欢array_merge 函数而不是数组联合运算符(“+”)。

【讨论】:

  • 感谢您的意见。虽然我认为你的意思是 $w = ($new + $w) // not necessarily equal to $w += $new; 是我展示的方式。
  • 这只是一个“外围注释”,谢谢,我编辑添加了“CAUTION”... PHP 对每个“数组合并口味”都有不同的行为 :-) 但你的问题是关于 关联数组,所以我还用array_merge 完成了“关联解决方案”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-23
  • 2018-10-21
  • 2022-01-03
  • 2020-02-25
  • 2019-11-12
  • 1970-01-01
  • 2023-02-09
相关资源
最近更新 更多