最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

html - Order of the associative array in JavaScript by key and access by index - Stack Overflow

programmeradmin1浏览0评论

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'. 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, e.g.

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

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'. 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, e.g.

var arrkeys = ['alz','aly','alx','alw'];
Share Improve this question edited Jul 15, 2020 at 1:07 Peter Mortensen 31.6k22 gold badges110 silver badges133 bronze badges asked Dec 29, 2012 at 21:19 biztigerbiztiger 1,4874 gold badges23 silver badges40 bronze badges 15
  • 2 The key is the index. There is no other [semantic] ordering. – Lightness Races in Orbit Commented Dec 29, 2012 at 21:21
  • 4 That's not how associative arrays work in JavaScript; they're basically objects and the order of the properties is unknown. – BenM Commented Dec 29, 2012 at 21:21
  • By using non-numeric text in the key, you've converted it to an object. In other words, there is no "associative array." Associative arrays === objects – jeremy Commented Dec 29, 2012 at 21:21
  • arr={} is an object not an array. – The Alpha Commented Dec 29, 2012 at 21:22
  • 1 @Nile: I see no reason to assume that it's a typo. More likely it's another instance of the mon misconception. :) – Lightness Races in Orbit Commented Dec 29, 2012 at 21:24
 |  Show 10 more ments

5 Answers 5

Reset to default 5

Ordering of the object's properties is 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. That's why using it like you did - providing a separate array for ordering of the indexes - is another mon 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' }
];

How about adding some syntactic sugar in the form of an OrderedObject object? 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.

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). 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.

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'; then the index will not be updated. 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. This would allow the new object to more seamlessly and smoothly act like the ideal OrderedObject I am imagining.

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

发布评论

评论列表(0)

  1. 暂无评论