Javascript中以对象作为键值的数组

Javascript中以对象作为键值的数组,javascript,arrays,client-side,keyvaluepair,Javascript,Arrays,Client Side,Keyvaluepair,我有以下要求。我有一对作为键的整数和另一对作为值的整数。即: obj[{key1:12,key2:23}]=[2,3]; obj[{key1:12,key2:22}]=[4,3]; obj[{key1:34,key2:12}]=[4,33]; 最后,当这个列表的填充结束时,我想按顺序访问对象/数组的元素 现在我的理解是,对于这种以对象为键的数组,它们被称为关联数组,Javascript不支持它们 以下是我将在此结构上执行的操作: 插入:我将有像(2,3)或(2,4)这样的键,我想用一个新的

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

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

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

obj[{key1:34,key2:12}]=[4,33];
最后,当这个列表的填充结束时,我想按顺序访问对象/数组的元素

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

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

  • 插入:我将有像(2,3)或(2,4)这样的键,我想用一个新的键值对(如[1,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方法来获取对象的字符串等价物,然后使用索引


    其次,我尝试使用包含子对象的对象键创建对象。与这个答案大致相同的东西:。但是,我不确定在完成插入阶段后如何获得对所有元素的顺序访问

    您可能不会太喜欢这个,但它至少会给您一个稳定的键:

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


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

    您可能不会太喜欢这个类,但它至少会为您提供一个稳定的密钥:

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


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

    以下是一种面向对象的方法:

    // 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
    

    这里拉小提琴:

    这里有一种面向对象的方法:

    // 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
    

    Fiddle here:

    我问对象
    {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
    
    //定义密钥对对象类型
    var MyKeyPair=函数(键1、键2){
    这个.key1=key1;
    这个.key2=key2;
    };
    //为此类型定义tostring
    //稍后obj[aKeyPairInstance]将
    //调用toString方法
    //如果不这样做,则[对象]
    //将返回toString
    MyKeyPair.prototype.toString=function(){
    //因为你知道只有键1和键2
    //你可以:
    //返回this.key1+“:”+this.key2;
    //下面是一个更一般的方法,但它需要成本
    //如果处理的数据量非常大,则需要更多的cpu时间
    //数据类型使用较短的版本。
    var-ret=[];
    为了(这件事){
    如果(这个有自己的财产(东西)){
    再推(物);
    返回推送(“:”);
    重新推(这[东西]);
    反向推力(“,”);
    }
    }
    返回ret.join(“”);
    };
    //制作一组密钥对对象
    变量键=[
    新的MyKeyPair(21,33),
    新的MyKeyPair(22,34),
    新的MyKeyPair(23,35),
    新MyKeyPair(24,36)
    ];
    //创建一个对象并赋予它属性
    //基于键对的tostring值
    var obj={};
    
    对于(var i=0,len=keys.length;i我询问对象
    {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
    
    //定义密钥对对象类型
    var MyKeyPair=函数(键1、键2){
    这个.key1=key1;
    这个.key2=key2;
    };
    //为此类型定义tostring
    //稍后obj[aKeyPairInstance]将
    //调用toString方法
    //如果不这样做,则[对象]
    //将返回toString
    MyKeyPair.prototype.toString=function(){
    //因为你知道只有键1和键2
    //你可以:
    //返回this.key1+“:”+this.key2;
    //下面是一个更一般的方法,但它需要成本
    //如果处理的数据量非常大,则需要更多的cpu时间
    //数据类型使用较短的版本。
    var-ret=[];
    为了(这件事){
    如果(这个有自己的财产(东西)){
    再推(物);
    返回推送(“:”);
    重新推(这[东西]);
    反向推力(“,”);
    }
    }
    返回ret.join(“”);
    };
    //制作一组密钥对对象
    变量键=[
    新的MyKeyPair(21,33),
    新的MyKeyPair(22,34),
    新的MyKeyPair(23,35),
    新MyKeyPair(24,36)
    ];
    //创建一个对象并赋予它属性
    //基于键对的tostring值
    var obj={};
    
    对于(var i=0,len=keys.length;i可以使用二维数组

    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[“\u 1”][“\u 2”]
    或者这个

    obj = {
          1: {
            2: [2,1]
          }
        };
    
    但您将被迫使用关联数组表示法
    obj[“1”][“2”]

    据我所知,使用类似于关联数组的方式访问对象属性并不是一种好的做法

    您可以使用二维数组

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