Найти уникальную коллекцию элементов

#javascript #arrays #dictionary #search

#javascript #массивы #словарь #Поиск

Вопрос:

У меня есть список карт, который содержит карты покемонов в «наборах». Данные извлекаются в формате JSON (форматирование / запрос вне моего контроля).

 let myList = `
  [{'hand': '1', 'cards': {'charmander','pikachu','squirtle'}},
   {'hand': '2', 'cards': {'charmander','gyarados','jigglypuff'}},
   {'hand': '3', 'cards': {'balbasaur','blastoise','mankey'}}]
  `;
  

Я не уверен, что я могу использовать, чтобы найти уникальную комбинацию в этом списке, т.Е. комбинация 3 будет уникальной, поскольку она не содержит никаких других карт из других рук.

Я создал карту и использовал превращение каждой руки в строку, которая будет использоваться в качестве ключа, а затем проверил, существует ли ключ уже. Но с приведенными выше данными я не уверен, как я могу гарантировать, что рука 3 действительно уникальна, поскольку в других картах других карт не существует.

 cards = JSON.parse(myList);
let cardMap = new Map();
cards.map((hands) => {
   let handAsStr = hands.cards.toString();
   let matchingValue = cardMap.has(handAsStr);
   if (matchingValue) {
      console.log("Entry exists - Not adding "   handAsStr );
   } 
   else {
      console.log("Adding: "   handAsStr )
      cardMap.set(handAsStr , {hand: hands.hand});
   }
});
  

Я думал о преобразовании имен в шестнадцатеричные значения, а затем о поиске, существует ли это шестнадцатеричное значение где-либо еще, но это кажется сложным и неэффективным.

Есть какие-нибудь указания?

Комментарии:

1. Преобразование myList в массив само по себе является большой задачей. Вы используете одинарные кавычки, а вместо {} карточек есть [] обертки. JSON.parse() не будет работать

2. Вы используете недопустимый объект для своих карточек, вы хотели использовать вместо него массив?

Ответ №1:

Предполагая наличие массива для cards , вы могли бы сосчитать все карты из всех наборов и отфильтровать массив, проверив карты, если у всех карт количество равно единице.

 function findUnique(array) {
    var count = new Map;
    array.forEach(({ cards }) => cards.forEach(c => count.set(c, (count.get(c) || 0)   1)));
    return array.filter(({ cards }) => cards.every(c => count.get(c) === 1));
}

var array = [{ hand: '1', cards: ['charmander', 'pikachu', 'squirtle'] }, { hand: '2', cards: ['charmander', 'gyarados', 'jigglypuff'] }, { hand: '3', cards: ['balbasaur', 'blastoise', 'mankey'] }];

console.log(findUnique(array));  

Ответ №2:

Ваша строка недопустима в формате JSON, я предлагаю изменить cards на массив и заменить ' на " .

После анализа с помощью JSON.parse() вы можете создать карту, используя reduce() , чтобы получить количество появлений каждой карты. Затем вы можете использовать эту карту для фильтрации своего списка и сохранить только те элементы, карточки которых появляются только один раз.

 const myList = `[
 {'hand': '1', 'cards': ['charmander','pikachu','squirtle']},
 {'hand': '2', 'cards': ['charmander','gyarados','jigglypuff']},
 {'hand': '3', 'cards': ['balbasaur','blastoise','mankey']}
]`;

const list = JSON.parse(myList.replace(/'/g, '"'));

const allCards = list.reduce((acc, { cards }) => {
  cards.forEach(x => acc[x] = acc[x] ? acc[x]   1 : 1);
  return acc;
}, {});

const uniqueItems = list.filter(({ cards }) => cards.every(x => allCards[x] === 1));

console.log(uniqueItems)  

Комментарии:

1. Спасибо, что указали на недопустимый JSON. Я неправильно написал это здесь из кода, над которым я работал.

Ответ №3:

Добавьте все элементы в массив в Set ( uniqueSet ). Перебирайте карточки с вложенными Array.forEach() . Если в card найден Map ( objByCardMap ), удалите текущий объект и объект, сохраненный вместе с картой в Map из Set . Разложите Set и верните массив уникальных элементов:

 const findUniqueHand = array => {
  const uniqueSet = new Set(array);
  const objByCardMap = new Map();
  
  // iterate the array and then the cards
  array.forEach(o => o.cards.forEach(c => {
    if(objByCardMap.has(c)) { // if a card is found in the Map
      uniqueSet.delete(objByCardMap.get(c)); // remove the object in the map
      uniqueSet.delete(o); // remove the current object
    }
    else objByCardMap.set(c, o); // add the card and it's object ot the map
  }));

  return [...uniqueSet];
}

const array = [{ hand: '1', cards: ['charmander', 'pikachu', 'squirtle'] }, { hand: '2', cards: ['charmander', 'gyarados', 'jigglypuff'] }, { hand: '3', cards: ['balbasaur', 'blastoise', 'mankey'] }];

const result = findUniqueHand(array);

console.log(result);