导航到Javascript对象中的上一个和下一个项目

Sta*_*arx 11 javascript javascript-objects

我想在给定对象项目的情况下向上和向下导航JavaScript对象.一个示例对象:

var items = {
   "5" : ["name", "link2"],
   "8" : ["name 2", "link 2"],
   "11" : ["name 3", "link 3"]
}
Run Code Online (Sandbox Code Playgroud)

现在,鉴于我有这个项目items["8"].我想分别得到上一个和下一个项目.

getItemBefore = function(index) {
    // index holds 8
    // should return "5"
}

getItemAfter = function(index) {
    // index hold 8
    // should return 11
}
Run Code Online (Sandbox Code Playgroud)

我该如何获得这些物品?

lem*_*nzi 12

对象保存的键可以作为数组检索Object.keys(<var>).数组中键的顺序是任意的; 你需要在索引之前对它们进行排序.选项是sort()数组的内置方法,这是特别有用的,因为可以提供自定义比较函数(见下文).默认顺序是按字母顺序排列

获得有序数组后,您只需要查找项目在数组中的位置并返回其中的下一个和前一个元素:

var keys = Object.keys(items).sort();
var loc = keys.indexOf(item);
Run Code Online (Sandbox Code Playgroud)

鉴于loc > -1(即项目存在):

  • 上一项:items[keys[loc-1]]但检查loc > 0(它不是第一项).
  • 下一项:items[keys[loc+1]]但是检查一下loc < keys.length(它不是最后一个).

Object.keys与Javascript 1.85+兼容; 这是旧版浏览器的解决方法.

替代订单

数字的

如果您希望键具有数字顺序,请使用此比较功能:

var keys = Object.keys(items).sort( function(a,b) {
    return b - a;
});
Run Code Online (Sandbox Code Playgroud)

创建(或修改)时间

如果要使用创建顺序而不是字母数字,则项目必须保留其创建时间.就像是:

<value>.index = Date.getTime();
items['<item>'] = <value>;
Run Code Online (Sandbox Code Playgroud)

然后,该sort()方法需要以下比较功能:

var keys = Object.keys(items).sort( function(a,b) {
    return b.index - a.index;
});
Run Code Online (Sandbox Code Playgroud)

这可以很容易地扩展到最后的修改顺序或类似.

创作顺序

请注意,前一个解决方案仅在项目间隔时间超过1毫秒时才有效,这适用于用户操作.如果项目添加得更快,请使用此项而不是时间戳:

<value>.index = Object.keys(items).length;
Run Code Online (Sandbox Code Playgroud)

或者,或者,使用对象中的项目数保留外部计数器.


lmo*_*son 2

这有点棘手,因为从技术上讲,根据 ECMAScript 规范,对象中属性的顺序是特定于实现的。这意味着该语言不能保证您每次访问属性时都将采用相同的顺序。如果您依赖于此,则可能会出现问题。

请参阅Chrome 中的此错误。它指出 Chrome 不承诺以任何特定顺序返回您的密钥,并且它已被标记为“WONTFIX”4-5 年了。这意味着你不能依赖 Chrome 中的这种行为,这是另一篇文章表明现在 IE9 也有同样的“问题”。

因此,我建议您创建自己的对象来管理密钥,并在幕后使用 JavaScript 对象来存储密钥。

这是我整理的东西,它不支持删除,也没有边界检查,但它应该可以满足您的目的。在这里摆弄。

function orderedObject()
{
     this.keys = [];
     this.keyIndex = {};
     this.store = {};
}


orderedObject.prototype.addItem = function(key,value)
{
     this.keyIndex[key] = this.keys.length;
     this.keys.push(key);
     this.store[key] = value;
}

orderedObject.prototype.getItem = function(key)
{
     return this.store[key];
}

orderedObject.prototype.getKeyBefore = function(key)
{
     return this.keys[this.keyIndex[key] - 1];
}

orderedObject.prototype.getKeyAfter = function(key)
{
     return this.keys[this.keyIndex[key] + 1];
}

var testObject = new orderedObject();

testObject.addItem("5" , ["name", "link2"]);
testObject.addItem("8" , ["name 2", "link 2"]);
testObject.addItem("11" , ["name 3", "link 3"]);

console.log(testObject.getKeyBefore("8"))
console.log(testObject.getKeyAfter("8"))
Run Code Online (Sandbox Code Playgroud)