2017-07-04 153 views
0

我想通過數組數組來過濾一個對象,獲取對象數組。用數組數組過濾對象的最有效方法是什麼?

像這樣:

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))

是否有一個更容易或更方便的方式來做到這一點?我需要經常做這個操作,我的目標將達到幾百個項目,所以我看到了一個潛在的瓶頸。

+0

我可能會去看一下Lodash(http://lodash.com/)公用事業 – Stratboy

+3

這正是我怎麼會做。如果你需要從中擠出更多的速度,我可能會試着將功能性方法展開爲純粹的程序化(即沒有「過濾」和「減少」,僅僅用「香草」來表示)和基準。不過,我還建議首先進行基準測試*,看看它是否如你所擔心的那樣慢(如果它是幾百個條目,那麼它應該是相當快的,除非你希望它像每秒百萬次)。你知道,「不成熟的優化是萬惡的根源」等等。 – Amadan

+0

只要注意'startsWith' - 'a.15'以'a.1'開頭,我懷疑這可能不是你想要的。 '(ch +「。」)。startsWith(arr [index] +「。」)'更可靠('a.15.'以'a.'開始,但不以'a.1.'開頭)。 – Amadan

回答

0

我將創建一個「基本」(字母)到「真實」鍵的映射,然後在創建對象時使用它將字母轉換爲真正的鍵。

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);

相關問題