Проверьте наличие дублированных объектов в массиве, динамически заполненном - PullRequest
1 голос
/ 29 марта 2019

Я пытаюсь построить структуру данных, в которой все элементы будут сгруппированы на основе ключа объекта.

Все работает нормально, за исключением того, что я не могу проверить, дублированы ли данные в новом массиве, так какэто вне цикла 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 ]

1 голос
/ 29 марта 2019

Вы можете сначала создать 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"}]
  ]
]
*/
1 голос
/ 29 марта 2019

Я бы порекомендовал использовать некоторые для проверки следующим образом

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))
1 голос
/ 29 марта 2019

Уменьшите массив до объекта, используя названия стран в качестве ключей. Объедините игроков, находящихся в одной стране, с объектом, указав имя игрока в качестве ключа.

Когда закончите, преобразуйте обратно в массив, используя 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...