2016-12-11 109 views
0

我有2個對象數組:itemsListitemsFetched。每個數組內的所有對象都具有相同的結構(鍵/值的數量)。其中一個按鍵具有相同的 '意義',但不同的名稱(ITEM_IDitemsListIDitemsFetched)。他們的價值觀是一樣的。過濾器和克隆對象屬性

我需要過濾itemsList陣列,只留下那有ITEM_ID值等於ID值上itemsFetched的對象。然後從itemsDetched數組(其與item_id = id匹配)複製(添加)鍵/值count到過濾數組。

我有一個工作代碼,但我確定它不是解決此問題的最佳方法。我已經問過類似的問題了(關於'filter'部分)解決了我的問題,但由於我必須在過濾之後添加'count'部分,所以我最終重構了整個問題。

itemsList(樣品)

[ 
    { 
     "id": 0, 
     "name": "Egg", 
     "img": "http://www.serebii.net/pokemongo/items/egg.png" 
    }, 
    { 
     "id": 1, 
     "name": "Pokeball", 
     "img": "http://www.serebii.net/pokemongo/items/20pokeballs.png" 
    }, 
    { 
     "id": 2, 
     "name": "Greatball", 
     "img": "http://www.serebii.net/pokemongo/items/greatball.png" 
    }, 
    { 
     "id": 401, 
     "name": "Incense", 
     "img": "http://www.serebii.net/pokemongo/items/incense.png" 
    }, 
    { 
     "id": 901, 
     "name": "Incubator (Unlimited)", 
     "img": "http://www.serebii.net/pokemongo/items/eggincubator.png" 
    } 
] 

itemsFetched(樣品)

[ 
    { 
    "item_id": 1, 
    "count": 50, 
    "unseen": true 
    }, 
    { 
    "item_id": 401, 
    "count": 2, 
    "unseen": true 
    }, 
    { 
    "item_id": 901, 
    "count": 1, 
    "unseen": true 
    } 
] 

resultArray(我想要的到底)

[ 
    { 
    "id": 1, 
    "name": "Pokeball", 
    "count": 50, 
    "img": "http://www.serebii.net/pokemongo/items/20pokeballs.png", 
    }, 
    { 
    "id": 401, 
    "name": "Incense", 
    "count": 2, 
    "img": "http://www.serebii.net/pokemongo/items/incense.png" 
    }, 
    { 
    "id": 901, 
    "name": "Incubator (Unlimited)", 
    "count": 1, 
    "img": "http://www.serebii.net/pokemongo/items/eggincubator.png" 
    } 
] 

我現在的代碼(工作)

let arr = []; 
itemsFetched.forEach((item) => { 
    itemsList.forEach((item2) => { 
    if (item.item_id === item2.id) { 
     arr.push({ 
     "id": item.item_id, 
     "name": item2.name, 
     "count": item.count, 
     "img": item2.img 
     }); 
    } 
    }); 
}); 

PS:我可以使用ES6/7語法/功能。

+0

最好在服務器上做這個處理。總是返回格式化到瀏覽器的數據。然後,您不必在每個需要此數據的頁面上執行相同的數據操作。 – Luke101

+0

是的,我意識到這一點。這是服務器端完成的。其中一個數組位於json文件及其模板上,另一個是對外部api調用的響應。 – nip

+0

他試圖從數組中獲取id。這裏--- >> if(itemsFetched.item_id === itemsList.id) –

回答

2

您可以使用哈希表來減少時間complexitly,你的算法是O(m*n),後續是O(m+n+r)

const itemsMap = itemsList.reduce((map, item) => { 
    map[item.id] = item 
    return map 
}, {}) 
const results = itemsFetched 
    .filter((item) => itemsMap.hasOwnProperty(item.item_id)) 
    .map((item) => ({ 
     id: item.item_id, 
     name: itemsMap[item.item_id].name, 
     count: item.count, 
     img: itemsMap[item.item_id].img, 
    })) 
+0

感謝您的意見。我會測試一下,看看它是如何發展的。 (還有,無處不在的控制檯日誌記錄瞭解eheh正在發生什麼) – nip

-1

是否這樣?

var itemsList = [ 
 
    { 
 
     "id": 0, 
 
     "name": "Egg", 
 
     "img": "http://www.serebii.net/pokemongo/items/egg.png" 
 
    }, 
 
    { 
 
     "id": 1, 
 
     "name": "Pokeball", 
 
     "img": "http://www.serebii.net/pokemongo/items/20pokeballs.png" 
 
    }, 
 
    { 
 
     "id": 2, 
 
     "name": "Greatball", 
 
     "img": "http://www.serebii.net/pokemongo/items/greatball.png" 
 
    }, 
 
    { 
 
     "id": 401, 
 
     "name": "Incense", 
 
     "img": "http://www.serebii.net/pokemongo/items/incense.png" 
 
    }, 
 
    { 
 
     "id": 901, 
 
     "name": "Incubator (Unlimited)", 
 
     "img": "http://www.serebii.net/pokemongo/items/eggincubator.png" 
 
    } 
 
]; 
 

 
var itemsFetched = [ 
 
    { 
 
    "item_id": 1, 
 
    "count": 50, 
 
    "unseen": true 
 
    }, 
 
    { 
 
    "item_id": 401, 
 
    "count": 2, 
 
    "unseen": true 
 
    }, 
 
    { 
 
    "item_id": 901, 
 
    "count": 1, 
 
    "unseen": true 
 
    } 
 
] 
 

 

 

 
let arr = []; 
 
itemsFetched.forEach((item) => { 
 
    itemsList.forEach((item2) => { 
 
    if (item.item_id == item2.id) { 
 
     arr.push({ 
 
     "id": item.item_id, 
 
     "name": item2.name, 
 
     "count": item.count, 
 
     "img": item2.img 
 
     }); 
 
    } 
 
    }); 
 
}); 
 

 
console.log(arr);

+0

這是如何更好? – 4castle

+0

什麼?我的代碼正在工作。我只想知道是否有更好的方法來做到這一點,而不是2個嵌套for-each + if + push。 (也許我應該添加我仍然學習ES6/7功能/語法,和陣列相關的功能,如.filter,.map,.includes) – nip

+0

抱歉,但你的代碼不工作:if(itemsFetched.item_id === itemsList.id),因爲你試圖從數組中獲取ID -_- –

0

一種改善的方法是使用for..of聲明,而不是forEach爲內循環。一旦id匹配,這有助於打破循環。沒有直接的方法可以打破forEach方法。

let arr = []; 
itemsFetched.forEach((item) => { 
    for (let item2 of itemsList) { 
    if (itemsFetched.item_id === itemsList.id) { 
     arr.push({ 
     "id": itemsFetched.item_id, 
     "name": itemsList.name, 
     "count": itemsFetched.count, 
     "img": itemsList.img 
     }); 
     break; 
    } 
    } 
}); 
+0

你的意思是'for ... of',這是ES6語法。 – gyre

+0

@gyre是〜https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of –

1

結合使用for ... of環路(一個ES6功能)與Array#map

第一次找到匹配項時returnreturn合併對象變得更容易,這是一個邏輯優化,因爲這兩個列表都不應包含給定的id以上的一個條目。

const result = itemsFetched.map(data => { 
    for (let item of itemsList) { 
    if (data.item_id === item.id) { 
     return { 
     id: item.id, 
     name: item.name, 
     count: data.count, 
     img: item.img 
     } 
    } 
    } 
}) 

段:

const itemsList = [{ 
 
    "id": 0, 
 
    "name": "Egg", 
 
    "img": "http://www.serebii.net/pokemongo/items/egg.png" 
 
}, { 
 
    "id": 1, 
 
    "name": "Pokeball", 
 
    "img": "http://www.serebii.net/pokemongo/items/20pokeballs.png" 
 
}, { 
 
    "id": 2, 
 
    "name": "Greatball", 
 
    "img": "http://www.serebii.net/pokemongo/items/greatball.png" 
 
}, { 
 
    "id": 401, 
 
    "name": "Incense", 
 
    "img": "http://www.serebii.net/pokemongo/items/incense.png" 
 
}, { 
 
    "id": 901, 
 
    "name": "Incubator (Unlimited)", 
 
    "img": "http://www.serebii.net/pokemongo/items/eggincubator.png" 
 
}] 
 

 
const itemsFetched = [{ 
 
    "item_id": 1, 
 
    "count": 50, 
 
    "unseen": true 
 
}, { 
 
    "item_id": 401, 
 
    "count": 2, 
 
    "unseen": true 
 
}, { 
 
    "item_id": 901, 
 
    "count": 1, 
 
    "unseen": true 
 
}] 
 

 

 
const result = itemsFetched.map(data => { 
 
    for (let item of itemsList) { 
 
    if (data.item_id === item.id) { 
 
     return { 
 
     id: item.id, 
 
     name: item.name, 
 
     count: data.count, 
 
     img: item.img 
 
     } 
 
    } 
 
    } 
 
}) 
 

 
console.log(result)

+0

首先,感謝您的意見。我已經開始看.map,但我不知道...。我會看看這個。另外,如果這是一個「合理大小的Web應用程序」,這些更改會提高服務器的性能,特別是對於...部分,因爲它在找到匹配之後會破壞?假設是的,這是否可以通知?或者只是一個小細節? – nip

+0

列表越長,性能差異就越重要。既然這是一個快速的解決方案,我寧願在安全的一面,並找到匹配時立即「返回」。 – gyre

+0

明白了。剛剛實施你的消化,它的工作。謝謝 ! – nip