【问题标题】:Find unique collection of items查找独特的项目集合
【发布时间】:2019-04-06 19:26:41
【问题描述】:

我有一张卡片列表,其中包含“套装”中的口袋妖怪卡片。数据以 JSON 格式检索(格式化/查询不在我的控制范围内)。

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

我不确定我可以利用什么来在该列表中找到唯一手牌,即手牌 3 将是唯一手牌,因为它不包含其他手牌中的任何其他牌。

我创建了一个地图并使用将每个 hand 转换为用作键的字符串,然后检查键是否已存在。但是根据上面的数据,我不确定如何确保手牌 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});
   }
});

我考虑将名称转换为十六进制值,然后搜索该十六进制值是否存在于其他任何地方,但这似乎令人生畏且效率低下。

任何指针?

【问题讨论】:

  • myList 转换为数组本身就是一项艰巨的任务。您正在使用单引号,并且卡片有 {} 包装而不是 []JSON.parse() 不起作用
  • 您正在为您的卡片使用无效的对象,您想使用数组来代替吗?

标签: javascript arrays dictionary search


【解决方案1】:

您的字符串不是有效的 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)

【讨论】:

  • 感谢您指出无效的 JSON。我没有从我正在处理的代码中正确编写它。
【解决方案2】:

将数组中的所有项目添加到Set (uniqueSet)。使用嵌套的 Array.forEach() 迭代卡片。如果在Map (objByCardMap) 中找到card,则删除当前对象,并将对象与卡片一起存储在地图中的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);

【讨论】:

    【解决方案3】:

    假设cards 的数组,您可以计算所有组的所有卡片,如果所有卡片的计数均为 1,则通过检查卡片来过滤数组。

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

    【讨论】:

      猜你喜欢
      • 2017-09-09
      • 1970-01-01
      • 2010-12-30
      • 1970-01-01
      • 2017-10-01
      • 2018-12-10
      • 1970-01-01
      • 2016-02-20
      • 2011-07-28
      相关资源
      最近更新 更多