检查动态填充的数组中的重复对象

时间:2019-03-29 16:43:48

标签: javascript arrays loops for-loop

我正在尝试建立一个数据结构,其中所有元素都将基于对象键进行分组。

一切正常,除了我无法检查新数组是否重复数据,因为它在for..of循环之外。我正在寻找一种方法,以防止push在新数组中已有另一个对象。

当前输出(请注意,来自日本的字符列表出现了两次)

[
  [
    { "country": "US" },
    [
      { "name": "Guile", "country": "US" }
    ]
  ],
  [
    { "country": "Japan" },
    [
      { "name": "E. Honda", "country": "Japan" },
      { "name": "Ryu", "country": "Japan" }
    ]
  ],
  [
    { "country": "Japan" },
    [
      { "name": "E. Honda", "country": "Japan" },
      { "name": "Ryu", "country": "Japan" }
    ]
  ],
  [
    { "country": "Thailand" },
    [
      { "name": "Sagat", "country": "Thailand" }
    ]
  ]
]

预期产量

[
  [
    { "country": "US" },
    [
      { "name": "Guile", "country": "US" }
    ]
  ],
  [
    { "country": "Japan" },
    [
      { "name": "E. Honda", "country": "Japan" },
      { "name": "Ryu", "country": "Japan" }
    ]
  ],
  [
    { "country": "Thailand" },
    [
      { "name": "Sagat", "country": "Thailand" }
    ]
  ]
]

我到目前为止所拥有的

var data = [
  {name: 'Guile', country: 'US'},
  {name: 'E. Honda', country: 'Japan'},
  {name: 'Ryu', country: 'Japan'},
  {name: 'Sagat', country: 'Thailand'}
]

const getNationList = (streetFighterList) => {
  let filteredList = []
  for (const [index, characterData] of streetFighterList.entries()) {
    // .......................................................
    // looking for ways here to check if `filteredList` already
    // has the data I'm trying to push. Since it's empty
    // I don't know how to check its index. :(
    // NOTE: indexOf() doesn't seem to work
    // .......................................................
    const indexOf = filteredList.indexOf(streetFighterList[index].country)
    if (indexOf == -1) {
      filteredList.push([
        { country: characterData.country },
        streetFighterList.filter((character) => {
          return character.country === characterData.country
        })
      ])
    }
  }
  return filteredList
}

console.log(getNationList(data))

注意:我了解,鉴于country对象始终是唯一的,如果我改用字符串,则此数据结构会更好,更容易。但这是示例数据,在现实生活中,我确实需要将其存储为对象。

3 个答案:

答案 0 :(得分:1)

以国家/地区名称作为键,将数组简化为对象。将同一国家/地区下的玩家与一个对象结合在一起,并以其名字作为键。

完成后,使用Object.values()转换回数组,并映射数组以通过Object.values()将播放器的对象转换为数组。

const data = [[{"country":"US"},[{"name":"Guile","country":"US"}]],[{"country":"Japan"},[{"name":"E. Honda","country":"Japan"},{"name":"Ryu","country":"Japan"}]],[{"country":"Japan"},[{"name":"E. Honda","country":"Japan"},{"name":"Ryu","country":"Japan"}]],[{"country":"Thailand"},[{"name":"Sagat","country":"Thailand"}]]]

const result = Object.values(data.reduce((r, [c, p]) => { 
  if(!r[c.country]) r[c.country] = [c, {}]
  
  const players = r[c.country][1];
  
  p.forEach(o => { if(!players[o.name]) players[o.name] = o; })
  
  return r;
}, {})).map(([c, p]) => [c, Object.values(p)]);

console.log(result)

答案 1 :(得分:1)

您可以先创建一个Set个独特国家,然后遍历它们,以将每个国家与该国的战斗机列表合并。例如:

const data = [
  {name: 'Guile', country: 'US'},
  {name: 'E. Honda', country: 'Japan'},
  {name: 'Ryu', country: 'Japan'},
  {name: 'Sagat', country: 'Thailand'}
];

const countries = new Set(data.map(x => x.country));
let countryData = [];
for (let c of countries) {
  countryData.push([{country: c}, data.filter(x => x.country === c)]);
}

console.log(countryData);
/*
[
  [
    {"country": "US"},
    [{"name": "Guile", "country": "US"}]
  ],
  [
    {"country": "Japan"},
    [{"name": "E. Honda", "country": "Japan"}, {"name": "Ryu", "country": "Japan" }]
  ],
  [
    {"country": "Thailand"},
    [{"name": "Sagat", "country": "Thailand"}]
  ]
]
*/

答案 2 :(得分:1)

我建议使用以下方法进行验证

var data = [
  {name: 'Guile', country: 'US'},
  {name: 'E. Honda', country: 'Japan'},
  {name: 'Ryu', country: 'Japan'},
  {name: 'Sagat', country: 'Thailand'}
]

const getNationList = (streetFighterList) => {
  let filteredList = []
  for (const [index, characterData] of streetFighterList.entries()) {

    const entry = filteredList.some(item => item[0].country === streetFighterList[index].country)
    if (!entry) {
      filteredList.push([
        { country: characterData.country },
        streetFighterList.filter((character) => {
          return character.country === characterData.country
        })
      ])
    }
  }
  return filteredList
}

console.log(getNationList(data))