Javascript可排序数组/对象结构和性能
在javascript中,如果对象应该保持排序顺序,则不能在对象中使用键/值对。相反,我们需要一个类似ES6Javascript可排序数组/对象结构和性能,javascript,arrays,performance,object,Javascript,Arrays,Performance,Object,在javascript中,如果对象应该保持排序顺序,则不能在对象中使用键/值对。相反,我们需要一个类似ES6map的数组 下面的内容似乎是构建它的一种方式。我放入id并将所有项包装到一个数组中。对于col块也有相同的想法 [ { id: 21, items: [ { col: 'name', data: { data1: 'hello', data2: 'world' }
map
的数组
下面的内容似乎是构建它的一种方式。我放入id
并将所有项
包装到一个数组中。对于col
块也有相同的想法
[
{
id: 21,
items: [
{
col: 'name',
data: {
data1: 'hello',
data2: 'world'
}
},
{
col: 'slug',
data: {
data1: 'hello',
data2: 'world'
}
}
]
},
{
id: 44,
items: [
{
col: 'name',
data: {
data1: 'hello',
data2: 'world'
}
},
{
col: 'slug',
data: {
data1: 'hello',
data2: 'world'
}
}
]
},
]
问题
这种方法的问题是,当它不能使用键/值对时,它需要遍历整个数组以查找id
44
。在现实生活中,不仅有两个群体,还有100个群体。科尔斯也是这样。每个项目组可能有20列。它需要遍历所有项目,以找到例如列slug
梦码
let result=get(44,'slug','data2');
问题:
- 上述结构是否良好且性能良好
- 我怎么能在没有表演命中的情况下介入呢
O(m*n)
复杂性,因为您需要检查每个组,然后检查其每个列,最后按名称获取数据(假设其复杂性为O(1)
)。有100个组和20个列,如果你抓住最后一项,最多也就是2000个操作。这应该是相当快的,因为你只需要做一个检查,看看这是否是正确的项目,并放弃其余的
尽管如此,如果速度太慢,并且需要进行大量查找,可以通过从数据生成一个查找表来降低将数据提取到O(1)
的复杂性,该表基本上如下所示:
21: {
y: 0,
cols: {
data1: 0
data2: 1
}
},
44: {
y: 1,
cols: {
data1: 0
data2: 1
}
}
+----------+-------------+----------+-------+
|组id |列名|数据键|值|
+----------+-------------+----------+-------+
|21 |姓名|数据1 |你好|
|21 |名称|数据2 |世界|
|21 |鼻涕虫|数据1 |你好|
|21 | slug |数据2 |世界|
|等等等等等等等等|
+----------+-------------+----------+-------+
可以使用嵌套贴图来表示:
const data=[{id:21,items:[{col:'name',data:{data1:'hello',data2:'world'}},{col:'slug',data:{data1:'hello',data2:'world'}]},{id:44,items:[{col col name',data:{data1:'hello',data2:'world'}}},{col slug',data:{data1:'hello',data2:'world'}}}},];
const lookupTable=新映射();
data.forEach(组=>{
如果(!lookupTable.has(group.id)){
lookupTable.set(group.id,newmap());
}
const groupLookupTable=lookupTable.get(group.id);
group.items.forEach(列=>{
//仅设置'data'对象
groupLookupTable.set(column.col,column.data);
})
})
函数get(id、col、data){
const group=lookupTable.get(id);
如果(!组)返回;
const columnData=group.get(col);
如果(!columnData)返回;
返回列数据[数据];
}
让result=get(44,'slug','data2');
console.log(result)
虽然@VLAZ的答案在很多情况下都很好,但这里有一个替代方法
function lookup(items) {
let results = {};
items.forEach((rows, y) => {
if (!(rows['id'] in results)) {
results[rows['id']] = {
y: y,
cols: {}
};
}
rows.items.forEach((cols, x) => {
results[rows['id']].cols[cols['col']] = x;
});
});
return results;
}
它将生成如下所示的查找对象:
21: {
y: 0,
cols: {
data1: 0
data2: 1
}
},
44: {
y: 1,
cols: {
data1: 0
data2: 1
}
}
然后使用另一个函数,我可以使用x和y从原始数组中获取正确的数据
更新
为了获取数据,我现在使用以下方法:
function getData(items, lookup, row, col) {
const x = lookup[row]['cols'][col];
const y = lookup[row]['y'];
return items[y]['items'][x];
}
let final = getData(data.rows, test, 28, 'meta_title');
console.log(final['data']);
我喜欢你的答案,并接受它作为这个问题的答案。后来,我发现带有映射的查找表在我的Vuex存储中感觉不正确。我仍然喜欢查找表的想法。因此,我添加了自己的备选答案。如果你愿意,你也可以看看这种方法。不管怎样,我都会接受你的回答。谢谢你所做的一切!