【问题标题】:array_splice() - Numerical Offsets of Associative Arraysarray_splice() - 关联数组的数值偏移
【发布时间】:2011-02-17 06:25:42
【问题描述】:

我正在尝试做某事,但找不到任何解决方案,我在将其投入使用时也遇到了一些麻烦,所以这里有一个示例代码,也许足以证明我的目标为:

$input = array
(
    'who' => 'me',
    'what' => 'car',
    'more' => 'car',
    'when' => 'today',
);

现在,我想使用array_splice() 从数组中删除(并返回)一个元素:

$spliced = key(array_splice($input, 2, 1)); // I'm only interested in the key...

上面将从$input(第一个参数)中删除并返回1个元素(第三个参数),在偏移量2(第二个参数),所以$spliced将保持值more .

我将使用 foreach 循环遍历 $input,我知道要拼接的密钥,但问题是我不知道它的 数字偏移量,因为 array_splice 只接受整数我不知道该怎么办。

一个很无聊的例子:

$result = array();

foreach ($input as $key => $value)
{
    if ($key == 'more')
    {
        // Remove the index "more" from $input and add it to $result.
        $result[] = key(array_splice($input, 2 /* How do I know its 2? */, 1));
    }
}

我首先使用array_search(),但它没有意义,因为它会返回关联索引....

如何确定关联索引的数字偏移量?

【问题讨论】:

  • 如果您只想从阵列中删除$input['more'],您可以使用unset($input['more']); 来执行此操作。
  • @Gumbo:我想删除并返回删除的元素(键)。我知道我可以使用unset(),但我很想知道是否可以使用array_splice()
  • 所有这些数组切片和骰子以及推送和移位功能通常在性能上非常昂贵。

标签: php arrays associative-array array-splice


【解决方案1】:

抓住价值并unsetting 是一种更好的方法(而且可能更快),但无论如何,你可以数数

$result = array();
$idx = 0; // init offset
foreach ($input as $key => $value)
{
    if ($key == 'more')
    {
        // Remove the index "more" from $input and add it to $result.
        $result[] = key(array_splice($input, $idx, 1));
    }
    $idx++; // count offset
}
print_R($result);
print_R($input);

给予

Array
(
    [0] => more
)
Array
(
    [who] => me
    [what] => car
    [when] => today
)

但是从技术上讲,关联键没有数字索引。如果输入数组是

$input = array
(
    'who' => 'me',
    'what' => 'car',
    'more' => 'car',
    'when' => 'today',
    'foo', 'bar', 'baz'
);

那么索引 2 是“baz”。但是由于array_slice 接受一个 offset,它与数字键不同,它使用在数组中该位置找到的元素(以元素出现的顺序),这就是为什么要计数有效。

在旁注中,使用数组中的数字键,您会得到有趣的结果,因为您正在测试相等性而不是身份。改为$key === 'more' 以防止“更多”被类型转换。由于关联键是唯一的,因此您也可以在找到“更多”后返回,因为检查后续键是没有意义的。但真的:

if(array_key_exists('more', $input)) unset($input['more']);

【讨论】:

  • 我希望有一个不使用计数器变量但确实非常奇怪的结果的解决方案...关联数组可能没有数字索引,但它有一个数字偏移量 - 顺序定义了哪些元素?
  • @Alix 更像是它们出现的顺序。由于您可以对数组进行排序,因此这不一定是定义它们的顺序。
  • 确实,请参阅下面的答案。 =)
  • 澄清上面的措辞不太好。我想说的是,数组键和它的偏移量是不一样的。偏移量指的是数组中该位置的一个元素,但该元素可以有任何键(assoc 或数字)。数组键不表示位置。甚至数字数组键也可以重新排序以随机顺序出现,因此偏移量 2 可以引用键为 12 的元素。我会将此澄清添加到上面的答案中,但随后它会变成 CW(这是最愚蠢的)功能”)。
【解决方案2】:

我找到了解决办法:

$offset = array_search('more', array_keys($input)); // 2

即使是“有趣”的数组,例如:

$input = array
(
    'who' => 'me',
    'what' => 'car',
    'more' => 'car',
    'when' => 'today',
    'foo', 'bar', 'baz'
);

这个:

echo '<pre>';
print_r(array_keys($input));
echo '</pre>';

正确输出:

Array
(
    [0] => who
    [1] => what
    [2] => more
    [3] => when
    [4] => 0
    [5] => 1
    [6] => 2
)

这是一个微不足道的解决方案,但到达那里有点晦涩。

感谢大家的帮助。 =)

【讨论】:

  • 如果您打算将其用作 $result = key(array_splice($input, array_search('more', array_keys($input)), 1));,请帮自己一个忙,并将其与 array_key_existsunset 进行基准比较;)
  • 请注意,array_keysarray_search 是 O(n),而 $array['more']unset($array['more']) 都是 O(1)。
  • @Gumbo:我知道使用 unset 更快,你如何达到 Big-O 表示法中的 1 和 n?我想学那个!
  • @Alix Axel: array_keys 创建一个包含所有键的数组;所以它必须迭代所有 n 键来创建该数组,因此 O(n)。 array_search 正在迭代整个数组,直到找到针;在最坏的情况下,针不在数组中,因此 O(n)。与此相反,数组访问始终是恒定的(即使在 PHP 中,数组是使用哈希表实现的),因此 O(1)。
  • @Alix Axel:您可以通过计算算法对长度为 n 的输入所执行的操作次数来建立限制行为。
【解决方案3】:
$i = 0;
foreach ($input as $key => $value)
{
    if ($key == 'more')
    {
        // Remove the index "more" from $input and add it to $result.
        $result[] = key(array_splice($input, $i , 1));

    }
    $i++;
}

【讨论】:

    猜你喜欢
    • 2010-12-19
    • 2017-12-31
    • 1970-01-01
    • 1970-01-01
    • 2010-10-27
    • 1970-01-01
    • 2013-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多