简体   繁体   English

筛选和克隆对象属性

[英]Filter and clone object properties

I have 2 arrays of objects: itemsList and itemsFetched . 我有2个对象数组: itemsListitemsFetched All of the objects inside each array have the same structure (nr of key/values). 每个数组内的所有对象都具有相同的结构(键/值的nr)。 One of those keys has the same 'meaning' but a different name ( item_id on itemsList , id on itemsFetched ). 其中一个按键具有相同的“意义”,但不同的名称(上itemsList ITEM_ID,itemsFetched ID)。 Their values are the same. 它们的值是相同的。

I need to filter the itemsList array and leave only the objects that have the item_id value equal to the id value on itemsFetched . 我需要过滤itemsList数组,只保留item_id值等于itemsFetchedid值的对象 Then copy(add) the key/value count from each object on the itemsFetched array (which matches the item_id=id) to the filtered array. 然后,将itemsFetched数组(与item_id = id匹配)上每个对象的键/值计数复制(添加)到过滤后的数组。

I've a working code but I'm sure it isnt the best way to solve this problem. 我有一个有效的代码,但我确定这不是解决此问题的最佳方法。 I've already asked something similar before (regarding the 'filter' part) which solved my problem, but since I had to add the 'count' part after the filtering, I ended up refactoring the whole thing. 我之前已经问过类似的问题(关于“过滤器”部分),它解决了我的问题,但是由于我必须在过滤后添加“计数”部分,所以最终重构了整个过程。

itemsList (sample) 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 (sample) itemsFetched (样本)

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

resultArray (what I want in the end) 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"
  }
]

my current code (working) 我当前的代码(工作)

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: I'm able to use ES6/7 syntax/features. PS:我可以使用ES6 / 7语法/功能。

You can use hash map to reduce Time complexitly, your algorithm is O(m*n) , The follow is O(m+n+r) 您可以使用哈希映射来复杂地减少时间,您的算法为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,
    }))

Use a for ... of loop (an ES6 feature) in conjunction with Array#map . for ... of循环(ES6功能)与Array#map结合使用。

This makes it much easier to return the merged object the first time you find a match, which is a logically optimization because neither list should contain more than one entry with a given id . 这使第一次找到匹配项时return合并对象变得更加容易,这在逻辑上是优化的,因为两个列表都不应该包含多个具有给定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
      }
    }
  }
})

Snippet: 片段:

 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) 

One way to improve is to use for..of statement instead of forEach for the inner loop. 一种改进的方法是使用for..of语句而不是forEach用于内部循环。 This helps break from the loop once the id matches. 一旦ID匹配,这有助于打破循环。 There is no direct way to break from forEach method. 没有直接方法可以脱离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;
    }
  }
});

Like this? 像这样?

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM