如何在javascript和两个查找值中定义一组键/值并按顺序迭代该组?

时间:2009-02-19 07:19:38

标签: javascript

我有一组键/值,例如orange = 123,banana = 4,apple = 567。如何将这些键/值存储在javascript对象中,以便我可以:

  1. 通过查找检索值,例如set [“orange”]应返回123和
  2. 按照添加键/值对的顺序对 集进行迭代
  3. 似乎对于1.对象文字是合适的,但迭代顺序不能保证,而对于2.一组键/值对(对象文字)将提供迭代顺序但不能查找基于密钥的价值。

    @ *感谢所有答案 - 这个问题不是常见问题吗?像jQuery这样的库不包含对这种类型的支持吗?

4 个答案:

答案 0 :(得分:7)

如何烹饪自己的列表构造函数?

function List(obj) {

  if (this instanceof List) {
   var t     = this,
       keys  = [];

    /* inititalize: add the properties of [obj] to the list, 
       and store the keys of [obj] in the private keys array */
    for (var l in obj) {
       keys.push(l);
       t[l] = obj[l];
    }
    /* public:
       add a property to the list 
    */
     t.add = 
         function(key, value) {
              t[key] = value;
              keys.push(key);
              return t; /* allows method chaining */
            };

    /* public:
       return raw or sorted list as string, separated by [separator] 
       Without [sort] the order of properties is the order in which 
       the properties are added to the list
    */
     t.iterate =
       function(sort,separator){
         separator = separator || '\n';
         var ret   = [],
             lkeys = sort ? keys.slice().sort() : keys;

         for (var i=0;i<lkeys.length;i++){
           ret.push(lkeys[i]+': '+t[lkeys[i]]);
         }
       return ret.join(separator);
      };

  } else if (obj && obj instanceof Object) {
     return new List(obj);

  } else if (arguments.length === 2) { 
     var a    = {};
     a[String(arguments[0])] = arguments[1];
     return new List(a);

  } else { return true; }

 /* the 'if (this instanceof List)' pattern makes
    the use of the 'new' operator obsolete. The 
    constructor also allows to be initialized with
    2 parameters => 'List(key,value)' 
 */
}

现在您可以将其保留(保留道具的顺序)或排序:

var myList = 
 List( { orange:123,
         banana:4,
         apple:567 }
     );
myList.add('peach',786);
alert(myList.iterate());
  /*=>output:
    orange: 123
    banana: 4
    apple: 567
    peach: 786
  */
or: alert(myList.iterate(1));
  /*=>output:
    apple: 567
    banana: 4
    orange: 123
    peach: 786
  */

答案 1 :(得分:2)

你的两个假设都是正确的。不保证对象文字以任何顺序返回键。

在不旋转自己类型的情况下执行此操作的唯一方法是维护一个有序的键列表:

var obj = {
    orange:123,
    banana:4,
    apple:567
}

var keys = ['orange', 'banana', 'apple'];

for (var i=0; i<keys.length; i++){
  value = obj[keys[i]]];
}

丑陋,我知道。

答案 2 :(得分:2)

一个简单的封装:

function Dictionary(p)
{
    if(!this.Add)
    {
        Dictionary.prototype.Add = function(a)
        {
            if(!a.length) {a = [a];}
            for(var i = 0, n=a.length; i<n; i++)
            {
                for(x in a[i])
                {
                    this[x] = a[i][x];
                    this.keys.push(x);
                }
            }
        }
    }

    this.keys = [];

    if(typeof(p)!='undefined') {this.Add(p);}
}

var a = new Dictionary({'orange':123, 'banana':4, 'apple':567});

alert(a.keys);//returns [orange,banana,apple]

alert(a.keys[0]);//returns orange

alert(a.orange) //returns 123

a.Add({'mango':88}); //another way to add data

a.Add([{kiwi:16},{grapefruit:79}]) //another way to add data

alert(a.keys);//returns [orange,banana,apple,mango,kiwi,grapefruit]

答案 3 :(得分:0)

你可以用不同的方式做到这一点:

var a = {'orange':123, 'banana':4, 'apple':567};

var b = new Object();
b['orange'] = 123;
b['banana'] = 4;
b['apple'] = 567;

var c = new Object();
c.orange = 123;
c.banana = 4;
c.apple = 567;

语法不同,但内部三个声明是等效的。