Javascript 在localStorage中存储有序对象/数组
我已经为我们的内部门户构建了这个chrome扩展。此门户中有一个表单,其中只有一个文本区域作为输入。用户通常以这种形式发布一组字符串。因此,我的扩展将这些值存储在本地提交上,并以相反的时间顺序显示用户在表单中发布的命令的历史记录 我目前所做的是将每个命令作为值存储,将当前时间戳作为键存储到localStorage中。如果用户两次发布相同的数据,则两个数据都存储为两个不同的键值对。在每次加载页面时,我从数组中的localStorage中检索所有键,并按逆时间顺序对数组进行排序。然后再次遍历该数组,创建另一个包含键值对对象的数组。然后我在DOM节点中将它们显示为输入命令的历史记录 现在这是一种效率非常低的方法,更好的方法是将所有键值对存储在一个JSON.stringifyed字符串中。每当用户两次发布相同的输入时,就应该为相同的命令覆盖timestamp的前一个值。简而言之,同一命令不应存储两次 有两种方法可以做到这一点。那就是我需要帮助的地方 第一种方法:创建单个对象,键作为命令,值作为当前时间戳。说:Javascript 在localStorage中存储有序对象/数组,javascript,arrays,sorting,iteration,local-storage,Javascript,Arrays,Sorting,Iteration,Local Storage,我已经为我们的内部门户构建了这个chrome扩展。此门户中有一个表单,其中只有一个文本区域作为输入。用户通常以这种形式发布一组字符串。因此,我的扩展将这些值存储在本地提交上,并以相反的时间顺序显示用户在表单中发布的命令的历史记录 我目前所做的是将每个命令作为值存储,将当前时间戳作为键存储到localStorage中。如果用户两次发布相同的数据,则两个数据都存储为两个不同的键值对。在每次加载页面时,我从数组中的localStorage中检索所有键,并按逆时间顺序对数组进行排序。然后再次遍历该数组,
var command = $('textarea').val();
var storageTank = JSON.parse(localStorage["MyTank"]);
storageTank[command] = new Date().getTime();
localStorage["MyTank"] = JSON.stringify(storageTank);
所以我的储水箱看起来像
{
"run": 1331916048253,
"stop": 1331916049963,
"modify":1331916086324,
"delete": 1331916099874
//and so on... Remember there can be as much as 1000 to 1500 of such commands,
//some of them very large
}
现在,我的数据存储为无序字典。每当大部分是onload时,我需要以相反的时间顺序显示它们,我必须创建一个对象数组,每个对象包含一个键命令和查询时间戳,并对其进行排序。
像这样[{run:1331916048253},{stop:1331916049963},{modify:1331916086324},{delete:1331916099874}]
第二种方法:我将命令存储在一个只包含一个属性的对象数组中,并简单地使用push、pop和reverse来维护时间顺序。像
var command = $('textarea').val();
var entity = {};
entity[command] = new Date().getTime();
var storageTank = JSON.parse(localStorage["MyTank"]);
storageTank.push(entity);
localStorage["MyTank"] = JSON.stringify(storageTank);
现在我的储液罐看起来像这样
[
{"run": 1331916048253},
{"stop": 1331916049963},
{"modify":1331916086324},
{"delete": 1331916099874}
]
现在,我不需要在每次我想显示的时候对它们进行排序,或者换句话说,在每次页面加载时对它们进行排序,因为表单提交会在同一页面上重定向。但是,如果在保存每个命令之前,我需要首先遍历数组,检查同一命令是否已经存在,如果已经存在,则覆盖,这将发生在表单提交时,这意味着在解决此问题之前,表单不会提交
现在哪种方式更有效
提前感谢。您的数据架构需要一种既能提供唯一性又能提供顺序的数据类型。 其他语言会自动为您提供排序哈希等,但在Javascript中,您需要在提供唯一性的对象或提供排序的数组之间进行选择 您提到您的storageTank对象包含许多对象,大约1000-1500个,所以让我们看看排序需要多长时间: 为了进行测试,我创建了这个函数,它生成了一个与您类似的对象,它使用下划线.js
function build (size) {
return _.chain(size)
.range()
.shuffle()
.map(function (v) {return {'command': v};})
.value();
}
console.log(build(10));
> [
{'command': 4},
{'command': 0},
{'command': 2},
{'command': 8},
{'command': 5},
{'command': 1},
{'command': 3},
{'command': 9},
{'command': 6},
{'command': 7}
]
因此,让我们看看按“command”键对该数组排序需要多长时间:
b = build(10);
console.time('a');
b.sort(function (a, b) {return a.command - b.command});
console.timeEnd('a')
a: 0ms
我对许多buildsize值重复了此测试,结果如下:
size: 10, time: 0ms
size: 20, time: 0ms
size: 40, time: 0ms
size: 80, time: 0ms
size: 160, time: 0ms
size: 160, time: 0ms
size: 320, time: 0ms
size: 640, time: 0ms
size: 1280, time: 1ms
size: 2560, time: 1ms
size: 5120, time: 3ms
size: 10240, time: 5ms
size: 20480, time: 10ms
size: 40960, time: 28ms
size: 81920, time: 43ms
size: 163840, time: 228ms
size: 327680, time: 444ms
size: 655360, time: 997ms
size: 1310720, time: 2330ms
因此,除非您的对象包含超过100K个条目,否则排序时间将保持在50ms以下,这对于人类来说是不可见的。即使您的对象包含那么多条目,JSON也会被删除。stringify将成为您的瓶颈,而不是排序
这意味着:排序非常快。使用第一种方法。您的数据架构需要一种同时提供唯一性和顺序的数据类型。 其他语言会自动为您提供排序哈希等,但在Javascript中,您需要在提供唯一性的对象或提供排序的数组之间进行选择 您提到您的storageTank对象包含许多对象,大约1000-1500个,所以让我们看看排序需要多长时间: 为了进行测试,我创建了这个函数,它生成了一个与您类似的对象,它使用下划线.js
function build (size) {
return _.chain(size)
.range()
.shuffle()
.map(function (v) {return {'command': v};})
.value();
}
console.log(build(10));
> [
{'command': 4},
{'command': 0},
{'command': 2},
{'command': 8},
{'command': 5},
{'command': 1},
{'command': 3},
{'command': 9},
{'command': 6},
{'command': 7}
]
因此,让我们看看按“command”键对该数组排序需要多长时间:
b = build(10);
console.time('a');
b.sort(function (a, b) {return a.command - b.command});
console.timeEnd('a')
a: 0ms
我对许多buildsize值重复了此测试,结果如下:
size: 10, time: 0ms
size: 20, time: 0ms
size: 40, time: 0ms
size: 80, time: 0ms
size: 160, time: 0ms
size: 160, time: 0ms
size: 320, time: 0ms
size: 640, time: 0ms
size: 1280, time: 1ms
size: 2560, time: 1ms
size: 5120, time: 3ms
size: 10240, time: 5ms
size: 20480, time: 10ms
size: 40960, time: 28ms
size: 81920, time: 43ms
size: 163840, time: 228ms
size: 327680, time: 444ms
size: 655360, time: 997ms
size: 1310720, time: 2330ms
因此,除非您的对象包含超过100K个条目,否则排序时间将保持在50ms以下,这对于人类来说是不可见的。即使您的对象包含那么多条目,JSON也会被删除。stringify将成为您的瓶颈,而不是排序
这意味着:排序非常快。使用第一种方法。您必须在javascript中存储有序列表或键值对之间进行选择,这是无法避免的。但是,V8引擎保留键/值对的顺序。尽管它需要通过大量测试进行验证/确认。您必须在javascript中存储有序列表或键值对之间进行选择,但这是无法避免的。但是,V8引擎保留键/值对的顺序。尽管需要通过大量测试进行验证/确认。迭代如何,需要多少时间
请问迭代是否接管排序?在您提到的1000-1500范围内,您不会看到迭代和排序之间有任何明显的区别。在数百万范围内,迭代将快得多。问题是,通过选择“迭代”解决方案,您必须确保数组总是按pop、push等手动排序。您在代码中引入的任何错误都可能破坏数据。排序解决方案更安全。如果我使用第一个选项,我将必须创建一个类似于第二个的结构来进行排序,因为只有数组可以排序,对吗?至于由于bug而分解数据,只要它能以正确的顺序显示最后10条命令,我就不太担心了。没错,你必须将对象推入数组中才能进行排序。那么迭代呢,迭代需要多少时间来完成排序?在您提到的1000-1500范围内,您不会看到迭代和排序之间有任何明显的区别。在数百万范围内,迭代将快得多。问题是,通过选择“迭代”解决方案,您必须确保数组总是按pop、push等手动排序。您在代码中引入的任何错误都可能破坏数据。排序解决方案更安全。如果我使用第一个选项,我将必须创建一个类似于第二个的结构来进行排序,因为只有数组可以排序,对吗?至于由于bug而分解数据,只要它能以正确的顺序显示最后10条命令,我就不太在意了。没错,为了进行排序,您必须将对象推入数组中。