Javascript可排序数组/对象结构和性能

Javascript可排序数组/对象结构和性能,javascript,arrays,performance,object,Javascript,Arrays,Performance,Object,在javascript中,如果对象应该保持排序顺序,则不能在对象中使用键/值对。相反,我们需要一个类似ES6map的数组 下面的内容似乎是构建它的一种方式。我放入id并将所有项包装到一个数组中。对于col块也有相同的想法 [ { id: 21, items: [ { col: 'name', data: { data1: 'hello', data2: 'world' }

在javascript中,如果对象应该保持排序顺序,则不能在对象中使用键/值对。相反,我们需要一个类似ES6
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存储中感觉不正确。我仍然喜欢查找表的想法。因此,我添加了自己的备选答案。如果你愿意,你也可以看看这种方法。不管怎样,我都会接受你的回答。谢谢你所做的一切!