1

我有以下要求。我有一对整数作为键和另一对整数作为值。那是:

obj[{key1:12,key2:23}]=[2,3];

obj[{key1:12,key2:22}]=[4,3];

obj[{key1:34,key2:12}]=[4,33];

最后,当这个列表的人口结束时,我想顺序访问对象/数组的元素。

现在我的理解是,对于这种以对象为键的数组,它们被称为关联数组,而 Javascript 不支持它们。

以下是我将在此结构上执行的操作:

  1. 插入:我将有像 (2,3) 或 (2,4) 这样的键,我想用新的键值对(例如 [1,2])将它们插入到数组中,

  2. 查找:我可能有一个像 (2,3) 这样的密钥对,它已经插入到这个数组中,我想取回它以便我可以修改它。

那是这样的:

if(obj[{key1:2,key2:3}])
   obj[{key1:2,key2:3}]=[2,5];
else 
   obj[{key1:2,key2:3}]=[2,-1];

关于如何在 Javascript 中实现这一点的任何建议?

编辑:这是我尝试过的两件事:

首先我把它做成一个对象数组。这种方法不起作用,因为环顾四周,我知道在这种情况下,Javascript 将调用 toString 方法来获取对象的字符串等价物,然后它将使用索引。

其次,我试图用包含子对象的对象键来做一个对象。类似于此答案的内容:Answer。但是,我不确定在完成插入阶段后如何顺序访问所有元素。

4

4 回答 4

2

你可能不会喜欢这么多,但它至少会给你一个稳定的密钥:

obj[JSON.stringify({key1:12,key2:23})]=[2,3];

所以,最大的问题是对象中的“键”(实际上是“属性”)必须是字符串,或者能够被字符串化。在您的示例中,{key1:12,key2:23}将始终被字符串化为[object Object]. 所以你永远不会得到一个唯一的密钥。获得该唯一键的唯一方法是真正序列化它,例如使用JSON.stringify方法。

请注意,在 IE8 上,我认为您必须包含一个 JSON 类。

于 2013-11-05T07:15:32.883 回答
1

这是一种面向对象的方法:

// Constructor
function AssociativeArray() {
  this.length = 0;
}

// Add or set value
AssociativeArray.prototype.set = function(key, value) {
  key = key.key1+'|'+key.key2;
  if(!this[key]) {
    this.length++;
  }
  this[key] = value;
};

// Lookup
AssociativeArray.prototype.get = function(key) {
  return this[key.key1+'|'+key.key2];
};

AssociativeArray.prototype.toString = function() {
  var k, arr = [];
  for(k in this) {
    if(this.hasOwnProperty(k) && k !== 'length') {
      arr.push(this[k]);
    }
  }
  return arr;
};

// Create Associative Array
var arr = new AssociativeArray();

// empty array
console.log(arr.toString(), 'length='+arr.length); // [] length=0

// add value
arr.set({key1:1, key2:2}, [1,1]);
console.log(arr.toString(), 'length='+arr.length); // [[1,1]] length=1

// add value
arr.set({key1:2, key2:1}, [2,2]);
console.log(arr.toString(), 'length='+arr.length); // [[1,1], [2,2]] length=2

// set value
arr.set({key1:2, key2:1}, [3,3]);
console.log(arr.toString(), 'length='+arr.length); // [[1,1], [3,3]] length=2

// lookup and set
if(arr.get({key1:2, key2:3})) {
  arr.set({key1:2, key2:3}, [2,5]);
} else {
  arr.set({key1:2, key2:3}, [2,-1]);
}
console.log(arr.toString(), 'length='+arr.length); // [[1, 1], [3, 3], [2, -1]] length=3

在这里摆弄:http: //jsbin.com/ohOwala/3/edit

于 2013-11-05T07:39:13.203 回答
1

您可以使用二维数组

var arr = [];
arr[2] = [];
arr[2][3] = [1, 2];

或者您可以使用对象并使用对象属性名称访问对

obj = {
  _2_3: [1, 2],
  _2_1: [4, 1],
  _1_2: [3, 2]
};

obj["_2_3"]并像这样或这样访问它们obj._2_3

或者你可以嵌套它们

obj = {
  _1: {
    _2: [2,1]
  }
};

所以你可以像这样obj["_1"]["_2"] 或者也许这样访问它们

obj = {
      1: {
        2: [2,1]
      }
    };

但是您将被迫使用关联数组表示法obj["1"]["2"] ,据我所知,使用关联数组访问对象属性的方式不是一个好习惯

于 2013-11-05T08:06:06.423 回答
0

我问这些对象{key1:2,key3:2}来自哪里,因为如果你可以控制它,你可以为那些负责对象到字符串转换的类型实现一个 toString 方法,这样它就可以用作属性名称。

//define keypair object type
var MyKeyPair = function(key1,key2){
  this.key1=key1;
  this.key2=key2;
};
//define tostring for this type
// later obj[aKeyPairInstance] will
// invoke the toString method
// if you don't do this then [Object object]
// would be returned for toString
MyKeyPair.prototype.toString=function(){
  //since you know there is only going to be key1 and key2
  // you could just:
  // return this.key1+":"+this.key2;
  //Here follows a more general approach but it'll cost
  // you more cpu time, if working with very large amounts
  // of data use the shorter version.
  var ret=[];
  for(thing in this){
    if(this.hasOwnProperty(thing)){
      ret.push(thing);
      ret.push(":");
      ret.push(this[thing]);
      ret.push(",");
    }
  }
  return ret.join("");
};

// make a bunch of keyPair objects
var keys = [
  new MyKeyPair(21,33),
  new MyKeyPair(22,34),
  new MyKeyPair(23,35),
  new MyKeyPair(24,36)
];

//create an object and give it properties
// based on the tostring value of the keypairs
var obj={};
for(var i = 0,len=keys.length;i<len;i++){
  obj[keys[i]]=[keys[i].key1,keys[i].key2];
};

console.log(obj);//<=this would not log any usefull info in IE
     //Use Chrome, Firefox, Opera or any other browser instead
于 2013-11-05T07:40:00.157 回答