使用数组数组过滤对象的最有效方法是什么?

时间:2017-07-04 07:36:28

标签: javascript arrays performance sorting object

我正在尝试通过数组数组过滤一个Object,获取一个对象数组。

像这样:

 let obj =
{
  "a.1":1,
  "a.2":2,
  "b.1":3,
  "b.2":4,
  "c.1":5,
  "c.2":6
}

let array = 
[
  ["a.1","b.1"],
  ["a"],
  ["b","c.1"]
]

let expectedResult = 
[
  {
    "a.1":1,
    "b.1":3,
  },
  {
    "a.1":1,
    "a.2":2,
  },
  {
    "b.1":3,
    "b.2":4,
    "c.1":5
  },
]

// this is what I came up with
const filterObjectByArray = (obj, arr) =>
    Object.keys(obj)
    .filter(ch => {
        for (var index = 0; index < arr.length; index++)
            if (ch.startsWith(arr[index]))
                return true;
    })
    .reduce((ret, key) =>{
        ret[key] = obj[key]
        return ret
    },{})
    
let result = array.map(arr => filterObjectByArray(obj, arr))

//kind of deepEqual
console.log(JSON.stringify(expectedResult) == JSON.stringify(result))

有更简单或更方便的方法吗?我需要经常做这个操作,我的对象最多会有几百个条目,所以我看到了这个潜在的瓶颈。

1 个答案:

答案 0 :(得分:0)

我会创建&#34; base&#34;的一种类型映射。 (信)到&#34;真实&#34;键,然后在创建对象时使用它将字母转换为真实键。

&#13;
&#13;
const obj = {
  "a.1": 1,
  "a.2": 2,
  "b.1": 3,
  "b.2": 4,
  "c.1": 5,
  "c.2": 6
};

const array = [
  ["a.1", "b.1"],
  ["a"],
  ["b", "c.1"]
];

const getBaseKey = (key) => key.match(/^[a-z]+/)[0]; // get the base of the key - the letter. If it's only one letter, you can use key[0]

/** create a one time map of keys by their base **/
const oobjKeysMap = Object.keys(obj).reduce((map, key) => {
  const baseKey = getBaseKey(key);
  const curr = map.get(baseKey) || [];
  curr.push(key);
  return map.set(baseKey, curr);
}, new Map());

const result = array.map((sub) => // iterate the array
  [].concat(...sub.map((k) => k in obj ? k : oobjKeysMap.get(getBaseKey(k)))) // create the least of "real" keys
  .reduce((ret, key) => { // create the object
    ret[key] = obj[key];
    return ret;
  }, {})
);

console.log(result);
&#13;
&#13;
&#13;