【问题标题】:PHP - Associative arrays: Changing keys for key value pair where value is a class objectPHP - 关联数组:更改键值对的键,其中值是类对象
【发布时间】:2012-07-20 16:40:13
【问题描述】:

我有一个如下形式的关联数组:

$input = array("one" => <class object1>,
               "two" => <class object2,
               ... //and so on);

$input 的键保证是唯一的。我还有一个名为moveToHead($key) 的方法,它将$input[$key] 元素移动到该关联数组的第0 个位置。我有几个问题:

  1. 是否可以确定关联数组的索引?
  2. 如何将对应 $key =&gt; $value 对的数组条目移动到索引 0 并保持 $key 原样?
  3. 实现上述两点的最佳方法是什么?

我本来想为第二点(子解决方案)做 array_flip,但后来发现 array_flip 只能在数组元素为 int 和 string 时完成。有什么指点吗?

【问题讨论】:

  • 它们的键是唯一的这一事实对问题很重要吗?
  • 我猜不是,但作为预防措施,我把它放在那里以便让讨论保持重点。

标签: php associative-array


【解决方案1】:

使用名为array_keys 的函数,您可以确定键的索引:

$keys = array_flip(array_keys($input));
printf("Index of '%s' is: %d\n", $key, $keys[$key]);

要在某个位置(例如开头)插入一个数组,有array_splice 函数。因此,您可以创建要插入的数组,从旧位置删除值并将其拼接:

$key = 'two';
$value = $input[$key];
unset($input[$key]);    
array_splice($input, 0, 0, array($key => $value));

array union operator 可能会发生类似的事情,但这只是因为您想移到顶部:

$key = 'two';
$value = $input[$key];
unset($input[$key]);
$result = array($key => $value) + $input;

但我认为这可能比array_splice 有更多开销。

【讨论】:

  • array_unshift - 由于涉及重新索引,再次 O(n) 时间复杂度。
  • 我更改了那个代码,我发现它做得太多了。但是不知道你是否真的可以摆脱 O(n)。
  • 好主意,我只是错过了那个。我将在我的类对象上尝试这个,并让你知道结果。 thnx :)
  • 编辑,因为我看到其他人也有数组联合运算符,并使 array_splice 示例更加突出,我认为这是一个很好的变体。
  • array_splice 正在用“0”替换键,但第二个联合运算符工作正常。
【解决方案2】:

关联数组的“索引”是关键。在数字索引数组中,“键”是索引号。

编辑:我收回。 PHP 的关联数组是有序的(类似于其他语言中的 Ordered Maps)。

但也许您真正想要的是关联数组的有序数组?

$input = array(array("one" => <class object1>),
               array("two" => <class object2>)
               //...
         );

【讨论】:

  • PHP 的数组是有序的哈希表,所以 order 是有意义的。类似于您在其他语言中使用ordered_map 等的内容;)
  • PHP 数组键 有序的!这就是为什么我们有像ksort()这样的函数
  • 我确实有@grammar31 描述的实现,但是移动搜索、删除、移动所有操作将具有 O(n) 时间复杂度。但是,我想在 O(1) 中做同样的事情。如果在 O(1) 中不可能,我们可以减少所需线性时间的常数吗?
【解决方案3】:

这是我想出的:

$arr = array('one' => 'Value1', 'two' => 'Value2', 'three' => 'Value3');

function moveToHead($array,$key) {
   $return = $array;
   $add_val = array($key => $return[$key]);
   unset($return[$key]);
   return $add_val + $return;
}

print_r(moveToHead($arr,'two'));

结果

Array
(
    [two] => Value2
    [one] => Value1
    [three] => Value3
)

http://codepad.org/Jcb6ebxZ

【讨论】:

  • 将不得不尝试类对象。无论如何,谢谢
  • 数组中的数据或对象类型无关紧要。
【解决方案4】:

你可以使用内部数组指针函数来做你想做的事:

$input = array(
    "one"   => "element one",
    "two"   => "element two",
    "three" => "element three",
);
reset($input); // Move to first element.
echo key($input); // "one"

你可以把unset的元素拿出来放在前面:

$input = array(
    "one"   => "element one",
    "two"   => "element two",
    "three" => "element three",
);
$key = "two";
$element = $input[$key];
unset($input[$key]);
// Complicated associative array unshift:
$input = array_reverse($input);
$input[$key] = $element;
$input = array_reverse($input);
print_r($input);

【讨论】:

  • 是的,我也在做同样的事情,但重点是,这需要两个 array_reverse 函数调用。 array_reverse 本身的运行时间复杂度为 O(n)。
猜你喜欢
  • 2013-12-27
  • 2019-04-01
  • 2022-12-01
  • 2018-12-03
  • 2018-10-06
  • 2021-11-17
  • 2016-10-31
  • 1970-01-01
  • 2018-09-06
相关资源
最近更新 更多