简体   繁体   English

JavaScript 中关联数组按键和按索引访问的顺序

[英]Order of the associative array in JavaScript by key and access by index

I have an associative array like:我有一个关联数组,如:

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

I need to find the previous and next key of any selected element.我需要找到任何选定元素的上一个和下一个键。 Say, for key 'aly' it will be 'alz' and 'alx'.比如说,对于键 'aly',它将是 'alz' 和 'alx'。 If possible, I want to access the array by index rather than the key.如果可能,我想通过索引而不是键来访问数组。

Currently, I am doing this using a separate array containing keys, eg目前,我使用包含键的单独数组来执行此操作,例如

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

Ordering of the object's properties is undefined .对象属性的顺序是undefined You can use this structure...您可以使用这种结构...

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

... though searching for the element with the given key (like 'give me the element which key is 'alz' ) is not as straight-forward as with simple object. ...虽然搜索具有给定键的元素(例如 'give me the element which key is 'alz' )并不像使用简单对象那样直接。 That's why using it like you did - providing a separate array for ordering of the indexes - is another common approach.这就是为什么像你一样使用它 - 提供一个单独的数组来排序索引 - 是另一种常见的方法。 You can attach this array to that object, btw:您可以将此数组附加到该对象,顺便说一句:

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

This is an object, not an array, and it sounds like you don't really want those strings to be keys.这是一个对象,而不是一个数组,听起来您并不真的希望这些字符串成为键。

How about a nice array?一个漂亮的数组怎么样?

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

If you have to know the order of everything, and still use the keys and values, try this:如果您必须知道所有内容的顺序,并且仍然使用键值,请尝试以下操作:

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

You can then access them sequentially as follows: arr[0].key and arr[0].value .然后您可以按如下方式依次访问它们: arr[0].keyarr[0].value Similarly, you can find siblings inside of the loop with the following:同样,您可以使用以下命令在循环内找到兄弟姐妹:

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;
}

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.请记住,这将返回一个新object而原始object将保持不变。

How about adding some syntactic sugar in the form of an OrderedObject object?如何以OrderedObject对象的形式添加一些语法糖? Then you could do something like this:然后你可以做这样的事情:

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'

The following code makes this work.下面的代码使这项工作。 See it in action in a jsFiddle .在 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);
   }
}

I made some decisions that may not work for you.我做了一些可能对你不起作用的决定。 For example, I chose to use an Object as the prototype rather than an Array , so that you could preserve enumerating your object with for (key in myObj) .例如,我选择使用Object作为原型而不是Array ,以便您可以保留使用for (key in myObj)枚举您的对象。 But it didn't have to be that way.但也不必如此。 It could have been an Array , letting you use the property .length instead of the function .length() and then offering an each function that enumerates the keys, or perhaps an .object() function to return the inner object.它可能是一个Array ,让您使用属性.length而不是函数.length()然后提供一个each函数来枚举键,或者可能是一个.object()函数来返回内部对象。

This could be a little awkward as you'd have to remember not to add items to the object yourself.这可能有点尴尬,因为您必须记住不要自己向对象添加项目。 That is, if you do myObj[key] = 'value';也就是说,如果你做myObj[key] = 'value'; then the index will not be updated.那么index将不会更新。 I also did not provide any methods for rearranging the order of things or inserting them at a particular position, or deleting by position.我也没有提供任何重新排列事物顺序或将它们插入特定位置或按位置删除的方法。 If you find my object idea useful, though, I'm sure you can figure out how to add such things.不过,如果你发现我的对象想法很有用,我相信你可以弄清楚如何添加这些东西。

With the newer versions of EcmaScript you can add true properties and make them non-enumerable.使用较新版本的 EcmaScript,您可以添加真正的属性并使它们不可枚举。 This would allow the new object to more seamlessly and smoothly act like the ideal OrderedObject I am imagining.这将使新对象更无缝、更流畅地像我想象的理想 OrderedObject 一样运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM