在PHP中通过整数索引访问关联数组

100

我想使用关联数组中的键/值对的索引来设置其值。例如:

$my_arr = array( "bling" => "some bling", "bling2" => "lots O bling" );
$my_arr[1] = "not so much bling";  // Would change the value with key bling2.

如何在不使用键字符串的情况下实现这个目标?

6个回答

206
使用array_keys函数。
$keys = array_keys($my_arr);
$my_arr[$keys[1]] = "not so much bling"; 

4
顺便提一句,为什么PHP开发者要创建这样一种不直观的访问数组的方式? - Marty
3
@Marty,这与PHP开发人员的实现方式关系不大,而更多地与您对数组工作原理的误解有关。从技术上讲,以上仍在使用关联名称。数值索引键和关联索引键之间没有任何关联。 - Gordon
2
你创建一个关联数组,因为你要查找的内容比它在数组中的位置更重要。我认为这是一个很好的观点。比如说你有一个以学生姓名为键、地址为值的数组。你可以通过学生的姓名来获取他的地址。数组的位置是无关紧要的。而且你可以按照“学生姓名”对数组进行排序。 - Donovan
@Gordon 从技术上讲这是正确的,但程序员提供的是一个数字而不是一个字符串。我认为这就是“不使用关键字符串”的意思。 - Donovan
2
@Albert,您正在将此数字映射到相应的键字符串。但这并不意味着array [1] === $ array ['foo']。数组仍然可以在$ array [1]中包含另一个值。请注意我并没有说您的解决方案是错误的。这是OP的假设。 - Gordon

30

数字索引和关联索引之间没有相关性。

当您想要使用键/值的数组索引设置关联数组的值时,必须使用给定的键,设置$array[1]与设置$array['foo']不同。

考虑这个数组:

print_r( array('foo', 'foo' => 'bar', 'baz', 'some' => 'value') );
这将会给出。
Array
(
    [0] => foo
    [foo] => bar
    [1] => baz
    [some] => value
)

在数组中,foo是第二个元素。这就是偏移量,但它与索引1没有任何关系。如上所示,在该数组中,索引1与baz相关联。错误的假设仅因为foo是第一个关联键就与实际数字键1有关。就像some不对应2一样。

同样的,在上面展示的混合数组中,此站点其他地方推荐使用array_keys的解决方案将无法工作,因为......

print_r( array_keys(array('foo', 'foo' => 'bar', 'baz', 'some' => 'value')) );

会给出

Array
(
    [0] => 0
    [1] => foo
    [2] => 1
    [3] => some
)
所以当你使用 $array[$keys[1]] 时,实际上是在使用 $array['foo']。但如果你想要访问该数组中的第二个关联值 ('some'),你不能使用 $array[$keys[2]],因为那样会被解析为 $array[1],而那个值是 baz
元素的偏移量与其键或值完全无关。
print_r(
    array(
        100    => 'foo',
        'foo'  => 'bar',
        50     => 'baz',
        'some' => 'value'
    )
);

真正的意思

Array
( //key       value     offset/position
    [100]  => foo       // 0
    [foo]  => bar       // 1
    [50]   => baz       // 2
    [some] => value     // 3
)

这意味着偏移量为0的元素是“foo”,尽管其键为100。如果您想通过偏移量从数组中提取元素,必须使用

$third = array_splice($array, 2, 1);
echo $third[0]; // baz
这将创建一个只包含第三个元素的数组。
或者你可以使用ArrayIteratorArrayIterator实现了一个Seekable接口,让您可以在数组中寻找到特定的位置/偏移量,然后获取该位置的元素。
$iterator = new ArrayIterator($array);
$iterator->seek(3);
echo $iterator->current(); // value

1
小问题:“如果您想访问该数组中的第二个关联值('some'),则不能执行$array[$keys[2]],因为这将计算为$array[1],而那是baz。”从技术上讲,这是因为所有键,包括数字键,都是关联键——由array_keys返回的4个值。不存在“非关联键”的实体。如果您的意思是指出您无法返回第二个字符串键(通过假设键数组仅包含字符串),那么您所说的是正确的。$stringKeys = array_filter(array_keys($array), "is_string");可以提供字符串键。 - ToolmakerSteve

24

array_keys() 可以访问第n个键,而array_values()将给出第n个值。

<?php
$array = [
   0     => 'Zero',
   '1'   => 'One',
   'Two' => 'Two',
];
echo array_values($array)[2];
?>

将输出“Two”。

其中一个有优势吗?唯一我能看到的小优势是数组访问次数。

使用 array_keys() 需要 3 步。

  1. 从数据数组中获取键。
  2. 从键列表中获取第 n 个键。
  3. 使用第 n 个键从数据数组中获取值。

而使用 array_values(),只需要 2 步。

  1. 从数据数组中获取值。
  2. 从值列表中获取第 n 个值。

但另一方面,键通常较小,数据可能会嵌套得非常深,所以总体而言,使用 array_keys() 可能更安全。


7
如果数组很大,使用array_keysarray_values都会浪费资源,因为它们会分配一个与原始数组大小相同的新数组,只是为了获取第n个键(或值)。 array_slice接受一个整数偏移量,并可用于关联数组。您可以使用它以恒定时间获取(和设置)第n个键。
// This will at most allocate 2 temporary arrays of 1 element each
$key = array_keys(array_slice($array, $n, 1, true))[0];

$array[$key] = $value;

3
这里的解决方案很不错! - Daan

1

试一下,它适用于您。

$result= array_values($my_arr); // Array with indexes you need

1
请注意,在一个已经有多个回复和被接受的答案的旧帖子上发表评论时要小心。您需要解释为什么您的新答案比现有的更好。 - APC
我知道这是一个非常老的评论,但它不需要“更好”。它只需要为已经提供的内容增加一些价值。 - CubicInfinity

0

另一种可能性是将其转换为普通数组:

$arraybuff = implode("~~~",$my_arr);
$my_arr = explode("~~~",$arraybuff);

其中"~~~"是一个在您的数据中不会出现的分隔符。

现在,您可以使用等于偏移量的数字索引访问数组。

如果您仍然需要保留关联数组,请将其分配给另一个变量。


由于您应该始终考虑到这个确切的分隔符可能出现在您的数据中,所以这个想法只适用于99.9999999%的情况。有几种解决方案可以100%地工作。此外,这将使处理器为仅使用简单数组访问的操作而执行大量工作并浪费内存。 - user426486

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