如何让php数组拥有重复键?当我尝试插入一个键,具有已存在键的值对时,它会用新值覆盖相应前一个键的值。有没有办法可以维护两个具有不同值的重复键?
答案 0 :(得分:55)
你可以拥有一个具有数组值(也就是多维数组)的键,它将包含具有该给定键的所有元素。一个例子可能是
$countries = array(
"United States" => array("California", "Texas"),
"Canada" => array("Ontario", "Quebec")
);
答案 1 :(得分:29)
$array[$key][] = $value;
然后您可以通过以下方式访问它:
echo $array[$key][0];
echo $array[$key][1];
等
请注意,您正在使用此方法创建数组数组。
答案 2 :(得分:13)
数组的重点是拥有唯一键。如果要存储值对,则:
$array[] = [$value1, $value2];
如果你有很多傻瓜,那么这种替代方案会更有效率:
<?php
if (array_key_exists($key, $array))
$array[$key]['occurrences']++;
else
$array[$key] = ['value'=>$value, 'occurrences'=>1];
答案 3 :(得分:7)
PHP不允许这样做。最好的解决方案是使用多维数组。例如......
<?php
$mArray = array(array("key1" => "value1"),
array("key2" => "value2"),
array("key3" => "value3"),
array("key1" => "value4"));
?>
请注意我有多个名为key1
的重复键。
现在,如果我想调用key1
的每个实例,请运行
<?php
$desiredKeyName = "key1";
foreach ($mArray as $aValue) {
foreach ($aValue as $key => $value) {
if ($key == $desiredKeyName) {
echo $value . "<br />";
}
}
}
?>
它会返回
value1
value4
答案 4 :(得分:5)
我告诉你:存档数组
样本用法。
<?php
$arch = new archiveArray(); //Class setup
// Set and overwrite the data few times
$arch -> data = 'one';
$arch -> data = 2;
$arch -> data = 'tree XD';
// Get the latest data, as per expected behaviour of an array object
var_dump( $arch -> data ); // 'tree XD'
// Get its previously set archived values
var_dump( $arch -> getArchived( 'data' ) ); // ['one', 2]
?>
班级代码
<?php
///
/// An object array, which keeps an archived copy
/// of all its previously set values.
///
/// @author eugene@picoded.com
///
class archiveArray {
public $arch_data = array();
public $arch_archive = array();
public function archiveArray() {
$arch_data = array();
$arch_archive = array();
}
public function setData($name, $value) {
if( array_key_exists( $name, $this -> arch_data ) ) {
if( !array_key_exists( $name, $this -> arch_archive ) ) {
$this -> arch_archive[ $name ] = array();
} else {
if( !is_array($this -> arch_archive[ $name ] ) ) {
$this -> arch_archive[ $name ] = array();
}
}
array_push( $this -> arch_archive[ $name ] , $this -> arch_data[ $name ] );
}
$this -> arch_data[ $name ] = $value;
}
public function getData($name) {
return $this -> arch_data[ $name ];
}
public function getArchived($name) {
if( array_key_exists( $name, $this -> arch_archive ) ) {
return $this -> arch_archive[ $name ];
}
return null;
}
//!!!--- OVERLOAD functionalities START ---!!!//
public function __set($name, $value) { //Uses the 'set' to create a node in the default type setting
$this -> setData($name, $value);
}
public function __get($name) {
return $this -> getData($name);
}
//!!!--- OVERLOAD functionalities END ---!!!//
}
?>
TLDR:有时你需要像这样的黑客来快速完成工作!
他的问题可能引起强烈争议,并且违背了计算机科学的教义。 (在拍摄之前,请阅读整篇文章)但有些情况下您希望这种情况发生。 = X
例如,您有一个代码库,它操作一组指定的数组对象。并且由于它的重复使用(循环?,递归?)。它会覆盖或重新定义结果。直到最后一组给出。
当你完成所有事情的时候。您突然意识到您的客户(或您的)规格发生了变化。您需要中间的每个数据(而不是最终数据)(因此每个键需要多于1个数据)。在不幸的情况下,你的系统已经以如此复杂的方式完成了,很容易让!@#$改变一切,以便轻松地使用多维数组(意味着替换不起作用,特别是如果你正在使用动态调用)。那么你做什么&gt; ??
这实际上是我最近遇到的情况,但是有一个简单的黑客攻击,仍然可以确保所有代码仍然有效,同时仍保留旧数据。
最终结果,一个仍然可以像任何其他对象一样对待的类。但是获得了存档能力,以保留旧数据。它排序一个多维数组,直接访问[0]索引。它只需通过使用此对象更改变量声明即可。对对象参数所做的任何更改都将被存档。为了便于访问,整个代码程序的变化很小或没有变化=)
答案 5 :(得分:4)
我在处理个人项目时提出了一个简单的解决方案。
由于我想要某种重复的密钥,我决定以相反的顺序值=&gt;键存储我的数组key =&gt;值,其中value成为密钥,密钥成为值,这样我就可以重复实际上是价值观的钥匙。我没有创建重复的值,所以它适用于这种特定情况。
这是一个小例子:
$r = array ( 'banana'=>'FRUIT', 'apple'=>'FRUIT', 'broccoli'=>'VEG', 'peas'=>'VEG' );
function get_food_group ( $type, $bowl ) {
return array_keys ( $bowl, $type );
}
print_r ( get_food_group('FRUIT', $r) );
# PRINTS #
# Array
# (
# [0] => banana
# [1] => apple
# )
如果您有类似的话:
array (
'banana' => 'FRUIT',
'peach' => 'FRUIT',
'banana' => 'YELLOW'
)
然后我会选择其他解决方案。
答案 6 :(得分:2)
并不是说“你做不到”。当你真正尝试使用它时,具有重复键的数组的缺点变得明显。
$array['duplicate']
次访问,您只能看到第一个条目。foreach
中使用这样一个对象,它可以看到每个键/值对而不管它是否含糊不清。无论如何,还要逐字回答这个问题:你可以使用PHPs数组语法但是有一个累积对象而不是:
class DuplicateArray implements ArrayAccess, Iterator, Countable {
var $keys = array(),
$values = array();
var $pointer = 0;
// initialize from array
function __construct($from=array()) {
$this->keys = array_keys($from);
$this->values = array_values($from);
}
// iteration
function count() {
return count($this->keys);
}
function current() {
return $this->values[$this->position];
}
function key() {
return $this->keys[$this->position];
}
function next() {
$this->position++;
}
function rewind() {
$this->position = 0;
}
function valid() {
return isset($this->keys[$this->position]);
}
// just fetches the first found entry
function offsetGet($key) {
if (($i = array_search($key, $this->keys)) !== FALSE) {
return $this->values[$i];
}
else trigger_error("Undefined offset '$key'", E_USER_NOTICE);
}
// will only append new entries, not overwrite existing
function offsetSet($key, $value) {
$this->keys[] = $key;
$this->values[] = $value;
}
// removes first matching entry
function offsetUnset($key) {
if (($i = array_search($key, $this->keys)) !== FALSE) {
unset($this->keys[$i]);
unset($this->values[$i]);
// keep entries continuos for iterator
$this->keys = array_values($this->keys);
$this->values = array_values($this->values);
}
}
function offsetExists($key) {
return array_search($key, $this->keys) !== FALSE;
}
}
答案 7 :(得分:1)
正如porneL所说,数组的重点是键是唯一的。
如果要引用数组中的多个条目,则需要搜索数组值。
$arr=array(
0=>array('date'=>time(), 'ip'=>'127.0.0.1', url='index.php'),
1=>array('date'=>time(), 'ip'=>'192.168.1.2', url='index.php'),
2=>array('date'=>time(), 'ip'=>'127.0.0.1', url='other.php'));
$matches=retrieve_keys_matching_subkey($arr, 'ip', '127.0.0.1');
foreach ($matches as $i) {
print implode(' ', $arr[$i]) . "\n";
}
function retrieve_keys_matching_subkey($arr, $subkey, $value)
{
$out=array();
foreach ($arr as $key=>$sub) {
if ($sub[$subkey]===$value) {
$out=$key;
}
}
return $out;
}
如果维护索引,这显然会更有效。这个代码并非无足轻重。
如果您正在使用大型数据集,那么我强烈建议您使用DBMS来管理数据。如果这不切实际,请使用链表。
答案 8 :(得分:0)
只能通过多维数组实现