比较Array中的两个elemens,如果某些属性匹配,则更新第一个数组

时间:2018-02-16 18:51:16

标签: javascript arrays node.js mongodb mongoose

我有两个阵列。

allInventoryItems.length //100,000 objects

`allInventoryItems[0] // {
   name: 'Something',
   price: 200
}

currentInventory.length //~250 objects

`currentInventory[0] // {
   name: 'Something Else',
   price: 300
}

你明白了。

我想要做的是比较这两个数组,如果他们的name属性匹配,请将currentInventory的{​​{1}}属性更新为price price 1}}。

循环使用如此大量的对象的最佳,最快的方法是什么?我怎样才能这样做,以便我不必在allInventoryItems中循环100,000次?

这是我目前的模特:

allInventoryItems

更新: 抱歉没有更具体。

好的,所以我的收藏就像这样。

广告资源:Inventory

价格:Prices

现在,价格收集是所有项目,永远。 库存收集是用户在库存中的项目。

过程是,我想更新USER库存中的所有价格,其中包含来自价格收集的价格,其中库存[item] .market_hash_name和价格[item] .market_hash_name匹配。

谢谢!

3 个答案:

答案 0 :(得分:1)

您可以将其作为一个对象并将其用作哈希表,而不是将allInventoryItems作为数组。然后,查找将比查找数组中的每个项目更快。

 updatePrice() {
        let allInventoryItems = {};
        Price.find({})
          .then(items => {
            // this might be wrong depending on structure of items
            allInventoryItems[items[0].items.name] = items[0].items.price;
        })

        return new Promise((resolve, reject) => {
            Inventory.find({
            }).then(items => {
                // loop through currentItems.  
                // If allInventoryItems[currentItem.name] exists, set the price of currentItem to its value.  This lookup is O(1).
            });
        });
    }

答案 1 :(得分:1)

当您将所有项目存储在同一文档中时,我担心您可以带来很多改进,因为您总是需要更新整个文档。您仍然可以使用Map来避免嵌套循环。你仍然必须连续执行两个循环。

return Promise.all(Inventory.findOne({ appid: RequestConfig.appid.DOTA2 }), 
                   Price.findOne({ gameid: RequestConfig.appid.DOTA2 }))
              .then( ([inv, ref]) => {
    // Create a map, allowing to get an inventory item by name in constant time
    const map = new Map(inv.items.map(item => [item.market_hash_name, item]));
    for (const refItem of ref.items) {
        if (map.has(refItem.market_hash_name) {
            // Update a single price in the inventory document
            map.get(refItem.market_hash_name).price = ref.price;
        }
    )
    return inv.save(); // Update the whole inventory document, and return the promise
);

注意:请注意,您的代码使用promise construction anti-pattern:如果您已经拥有new Promise,请不要创建 String selectedFile = @"C:\path\to\file.sldprt"; String selectedVariable = "Variable Name"; String selectedVault = "My Vault Name"; vault = new EdmVault5(); vault.LoginAuto(selectedVault, 0); if (vault.IsLoggedIn) { IEdmFile5 file = vault.GetFileFromPath(selectedFile, out IEdmFolder5 folder); IEdmCard5 card = folder.GetCard(Path.GetExtension(selectedFile).Substring(1)); Object variableName = selectedVariable; IEdmCardControl7 cardControl = (IEdmCardControl7)card.GetControl(card.GetControlID(ref variableName)); if (cardControl.GetControlVariableList(file.ID, out String[] cardListStrings)) { foreach (String cardListItem in cardListStrings) { // do something with this string } } }

答案 2 :(得分:1)

一般来说,由于Inventory可能是一个小得多的列表,它将被迭代,然后它将是一个小得多的循环来进行查找和更新然后遍历整个{{1}收集并尝试在Price中找到可能的匹配项。例如,给出示例中的数字:Inventory的100,000个文档和Price的仅250个文档将节省99,750个无操作循环。

如果您使用节点8,则可以使用as {/等待cursors来限制内存处理量。

Inventory