如何在php数组中允许重复键
如何允许php数组具有重复的键?当我尝试插入一个键、值对和已经存在的键时,它会用新值覆盖相应的前一个键的值。有没有一种方法可以使两个重复的键都具有不同的值?数组的整个要点就是拥有唯一的键。如果要存储成对的值,则:如何在php数组中允许重复键,php,arrays,duplicates,Php,Arrays,Duplicates,如何允许php数组具有重复的键?当我尝试插入一个键、值对和已经存在的键时,它会用新值覆盖相应的前一个键的值。有没有一种方法可以使两个重复的键都具有不同的值?数组的整个要点就是拥有唯一的键。如果要存储成对的值,则: $array[] = [$value1, $value2]; 如果您有许多重复,则此替代方案将更有效: <?php if (array_key_exists($key, $array)) $array[$key]['occurrences']++; else
$array[] = [$value1, $value2];
如果您有许多重复,则此替代方案将更有效:
<?php
if (array_key_exists($key, $array))
$array[$key]['occurrences']++;
else
$array[$key] = ['value'=>$value, 'occurrences'=>1];
您可以有一个具有数组(也称为多维数组)值的单个键,该数组将包含具有给定键的所有元素。一个例子可能是
$countries = array(
"United States" => array("California", "Texas"),
"Canada" => array("Ontario", "Quebec")
);
然后,您可以通过以下方式访问它:
echo $array[$key][0];
echo $array[$key][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来管理数据。如果不可行,则使用链接列表。我向您介绍:归档阵列
示例用法
<?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个数据)。不幸的是,您的系统已经以如此复杂的方式完成了,这是一件痛苦的事!@#将所有内容更改为易于使用多维数组(这意味着替换将不起作用,尤其是在使用动态调用时)。那你是怎么做的
这实际上是我最近遇到的一个场景,但是有一个简单的解决方法,它仍然确保所有代码仍然工作,同时仍然保留旧数据
最终的结果是,一个仍然可以像对待任何其他对象一样对待的类。但拥有存档能力,可以保存旧数据。它是一个多维数组,直接访问[0]索引。它的工作原理很简单,就是用这个对象更改变量声明。对对象参数所做的任何更改都将被存档。为了便于访问,只需对整个代码程序进行最小的更改或不进行任何更改(=)这并不是说“你做不到”。当您实际尝试使用具有重复键的数组时,它的缺点就显而易见了
- 您将失去单独处理内容的能力。对于
$array['duplicate']
访问,您将只看到第一个条目
- 因此,实际上,您只能在
foreach
中使用这样的对象,该对象可以查看每个键/值对,而不考虑模糊性
- 请参见下文,您还必须决定如何处理未设置的尝试,或者是否可以覆盖条目。仅附加模式最容易实现。(这就是egde的情况,它可能是有意义的。)
无论如何,要逐字回答以下问题:您可以使用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;
}
}
PHP不允许这样做。最好的解决方案是使用多维数组。例如
<?php
$mArray = array(array("key1" => "value1"),
array("key2" => "value2"),
array("key3" => "value3"),
array("key1" => "value4"));
?>
它会回来的
value1
value4
我在做一个个人项目时想出了一个简单的解决方案
因为我需要某种类型的重复键,所以我决定将数组key=>value以与value=>key相反的顺序存储,其中value变成key,key变成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'
)
然后我将使用另一种解决方案。如果多个可以具有相同密钥,您将如何访问所需的值?数组包含唯一密钥。因此,如果u对单个键具有多个值,请使用嵌套/多维数组。=)那是你最好的了。因此,只要接受Mike Lewis的回答并给他bounty=PHow,你会区分这两个键吗?你会如何将一个值关联到它们中的任何一个并检索它?PHP没有多维数组!它们是hierarchical@symcbean:“由于数组值可以是其他数组,所以也可以是树和多维数组。”-()@Alix Axel:手册中的那句话也错了。@symcbean:要不要分享你对多维数组的定义?在执行$array[$key][
之前,请确保你通过if(!isset($array[$key]))$array[$key]=array()之类的方法创建了一个数组;
@isra:不需要这样做。php自己做;)是的,在这种情况下,不会生成通知。好的,这可以解决他的问题,但如果有人需要按嵌套数组的第一个元素对其排序怎么办?有没有合理的方法?我如何向united states的数组中插入值?@MoDarwish你会这样做吗它是这样的:$countries[“美国”][]=“你的价值”
$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'
)