2016-12-11 110 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