2

我有一个关联数组,例如:

var arr = {};
arr['alz'] = '15a';
arr['aly'] = '16b';
arr['alx'] = '17a';
arr['alw'] = '09c';

我需要找到任何选定元素的上一个和下一个键。比如说,对于键“aly”,它将是“alz”和“alx”。如果可能的话,我想通过索引而不是键来访问数组。

目前,我正在使用包含键的单独数组来执行此操作,例如

var arrkeys = ['alz','aly','alx','alw'];
4

5 回答 5

5

对象属性的排序是undefined。你可以使用这个结构...

[{ key: 'alz', value: '15a'},
 { key: 'aly', value: '16b'},
 { key: 'alx', value: '17a'}]

...尽管使用给定键搜索元素(例如“给我是的元素” key'alz'并不像使用简单对象那样直接。这就是为什么像你一样使用它——为索引的排序提供一个单独的数组——是另一种常见的方法。您可以将此数组附加到该对象,顺便说一句:

var arr={};
arr['alz']='15a';
arr['aly']='16b';
arr['alx']='17a';
arr['alw']='09c';
arr._keysOrder = ['alz', 'aly', 'alx', 'alw'];
于 2012-12-29T21:22:35.153 回答
2

这是一个对象,而不是数组,听起来您并不真的希望这些字符串成为键。

一个漂亮的数组怎么样?

var ar = [
  { key: 'alz', value: '15a' },
  { key: 'aly', value: '16b' },
  { key: 'alx', value: '17a' },
  { key: 'alw', value: '09c' }
];
于 2012-12-29T21:23:03.553 回答
1

以对象的形式添加一些语法糖怎么样OrderedObject?然后你可以做这样的事情:

myObj = new OrderedObject();

myObj.add('alz', '15a');
myObj.add('aly', '16b');
myObj.add('alx', '17a');
myObj.add('alw', '09c');

console.log(myObj.keyAt(2)); // 'alx'
console.log(myObj.valueAt(3)); // '09c'
console.log(myObj.indexOf('aly')); // 1
console.log(myObj.length()) // 4
console.log(myObj.nextKey('aly')); // 'alx'

下面的代码使这项工作。在 jsFiddle 中查看它的实际效果。

function OrderedObject() {
   var index = [];
   this.add = function(key, value) {
      if (!this.hasOwnProperty(key)) {
         index.push(key);
      }
      this[key] = value;
   };
   this.remove = function(key) {
      if (!this.hasOwnProperty(key)) { return; }
      index.splice(index.indexOf(key), 1);
      delete this[key];
   }
   this.indexOf = function(key) {
      return index.indexOf(key);
   }
   this.keyAt = function(i) {
      return index[i];
   };
   this.length = function() {
      return index.length;
   }
   this.valueAt = function(i) {
      return this[this.keyAt(i)];
   }
   this.previousKey = function(key) {
      return this.keyAt(this.indexOf(key) - 1);
   }
   this.nextKey = function(key) {
      return this.keyAt(this.indexOf(key) + 1);
   }
}

我做了一些可能不适合你的决定。例如,我选择使用 anObject作为原型而不是 an Array,这样您就可以保留使用 枚举您的对象for (key in myObj)。但它不一定是那样的。它可能是一个Array,让您使用属性.length而不是函数.length(),然后提供一个each枚举键的函数,或者可能是一个.object()返回内部对象的函数。

这可能有点尴尬,因为您必须记住不要自己向对象添加项目。也就是说,如果您这样做myObj[key] = 'value';,则index不会更新。我也没有提供任何重新排列事物顺序或将它们插入特定位置或按位置删除的方法。但是,如果您发现我的对象想法有用,我相信您可以弄清楚如何添加这些东西。

使用较新版本的 EcmaScript,您可以添加真正的属性并使它们不可枚举。这将允许新对象更无缝、更流畅地运行,就像我想象的理想 OrderedObject 一样。

于 2012-12-29T22:48:28.257 回答
1

You may try this

function sortObject(obj, order)
{
    var list=[], mapArr = [], sortedObj={};
    for(var x in obj) if(obj.hasOwnProperty(x)) list.push(x);
    for (var i=0, length = list.length; i < length; i++) {
        mapArr.push({ index: i, value: list[i].toLowerCase() });
    }
    mapArr.sort(function(a, b) {
        if(order && order.toLowerCase()==='desc')
            return a.value < b.value ? 1 : -1;
        else return a.value > b.value ? 1 : -1;
    });
    for(var i=0; i<mapArr.length;i++)
        sortedObj[mapArr[i].value]=obj[mapArr[i].value];
    return sortedObj;
}
// Call the function to sort the arr object
var sortedArr = sortObject(arr); // Ascending order A-Z
var sortedArr = sortObject(arr, 'desc'); // Descending order Z-A

DEMO.

Remember, this will return a new object and original object will remain unchanged.

于 2012-12-29T22:18:20.770 回答
1

如果您必须知道所有内容的顺序,并且仍然使用键值,请尝试以下操作:

var arr = [
    { key: 'alz', value: '15a' },
    { key: 'aly', value: '16b' },
    { key: 'alx', value: '17a' },
    { key: 'alw', value: '09c' }
]; 

然后,您可以按如下顺序访问它们:arr[0].keyarr[0].value. 同样,您可以使用以下内容在循环内找到兄弟姐妹:

for(var i = 0; i < arr.length; i++)
{
    var previous_key = (i > 0) ? arr[(i - 1)].key : false;
    var next_key = (i < (arr.length - 1)) ? arr[(i + 1)].key : false;
}
于 2012-12-29T21:23:58.157 回答