[英]Order of the associative array in JavaScript by key and access by index
我有一个关联数组,如:
var arr = {};
arr['alz'] = '15a';
arr['aly'] = '16b';
arr['alx'] = '17a';
arr['alw'] = '09c';
我需要找到任何选定元素的上一个和下一个键。 比如说,对于键 'aly',它将是 'alz' 和 'alx'。 如果可能,我想通过索引而不是键来访问数组。
目前,我使用包含键的单独数组来执行此操作,例如
var arrkeys = ['alz','aly','alx','alw'];
对象属性的顺序是undefined 。 您可以使用这种结构...
[{ key: 'alz', value: '15a'},
{ key: 'aly', value: '16b'},
{ key: 'alx', value: '17a'}]
...虽然搜索具有给定键的元素(例如 'give me the element which key
is 'alz'
)并不像使用简单对象那样直接。 这就是为什么像你一样使用它 - 提供一个单独的数组来排序索引 - 是另一种常见的方法。 您可以将此数组附加到该对象,顺便说一句:
var arr={};
arr['alz']='15a';
arr['aly']='16b';
arr['alx']='17a';
arr['alw']='09c';
arr._keysOrder = ['alz', 'aly', 'alx', 'alw'];
这是一个对象,而不是一个数组,听起来您并不真的希望这些字符串成为键。
一个漂亮的数组怎么样?
var ar = [
{ key: 'alz', value: '15a' },
{ key: 'aly', value: '16b' },
{ key: 'alx', value: '17a' },
{ key: 'alw', value: '09c' }
];
如果您必须知道所有内容的顺序,并且仍然使用键和值,请尝试以下操作:
var arr = [
{ key: 'alz', value: '15a' },
{ key: 'aly', value: '16b' },
{ key: 'alx', value: '17a' },
{ key: 'alw', value: '09c' }
];
然后您可以按如下方式依次访问它们: arr[0].key
和arr[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;
}
你可以试试这个
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
演示。
请记住,这将返回一个新object
而原始object
将保持不变。
如何以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);
}
}
我做了一些可能对你不起作用的决定。 例如,我选择使用Object
作为原型而不是Array
,以便您可以保留使用for (key in myObj)
枚举您的对象。 但也不必如此。 它可能是一个Array
,让您使用属性.length
而不是函数.length()
然后提供一个each
函数来枚举键,或者可能是一个.object()
函数来返回内部对象。
这可能有点尴尬,因为您必须记住不要自己向对象添加项目。 也就是说,如果你做myObj[key] = 'value';
那么index
将不会更新。 我也没有提供任何重新排列事物顺序或将它们插入特定位置或按位置删除的方法。 不过,如果你发现我的对象想法很有用,我相信你可以弄清楚如何添加这些东西。
使用较新版本的 EcmaScript,您可以添加真正的属性并使它们不可枚举。 这将使新对象更无缝、更流畅地像我想象的理想 OrderedObject 一样运行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.