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