Все возможные комбинации с данными из файла JSON - PullRequest
1 голос
/ 17 июня 2019

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

[
 {
   "COLLECTION": "Assault",
   "WEAPON": "SG 553",
   "SKIN": "Tornado",
   "GRADE": "Consumer Grade"
 },
 {
   "COLLECTION": "Assault",
   "WEAPON": "UMP-45",
   "SKIN": "Caramel",
   "GRADE": "Consumer Grade"
 },
 {
   "COLLECTION": "Vertigo",
   "WEAPON": "Five-SeveN",
   "SKIN": "Candy Apple ",
   "GRADE": "Industrial Grade"
 }, ...
]

Комбинации будут создаваться следующим образом:

[
    "COMBINATION 1":[
     {
       "COLLECTION": "Assault",
       "WEAPON": "SG 553",
       "SKIN": "Tornado",
       "GRADE": "Consumer Grade"
     },
     {
       "COLLECTION": "Assault",
       "WEAPON": "UMP-45",
       "SKIN": "Caramel",
       "GRADE": "Consumer Grade"
     },
     {
       "COLLECTION": "Assault",
       "WEAPON": "Five-SeveN",
       "SKIN": "Candy Apple ",
       "GRADE": "Industrial Grade"
     }, ...
    ],

    "COMBINATION 2":[
     {
       "COLLECTION": "Assault",
       "WEAPON": "SG 553",
       "SKIN": "Tornado",
       "GRADE": "Consumer Grade"
     },
    {
       "COLLECTION": "Aztec",
       "WEAPON": "M4A4",
       "SKIN": "Jungle Tiger",
       "GRADE": "Industrial Grade"
     },
     {
       "COLLECTION": "Aztec",
       "WEAPON": "Tec-9",
       "SKIN": "Ossified",
       "GRADE": "Mil-Spec"
     }, ...
    ],...
]

Обратите внимание, что в этом случае обе комбинации имеют одинаковые элементы и поэтому не должныбыть отмеченным дважды.Это означает, что до тех пор, пока в комбинации есть элементы, которые совпадают с другой возможной комбинацией (независимо от того, в какой последовательности они находятся), она считается одной комбинацией (каждая комбинация будет иметь 10 элементов и будет отличаться от другой на основеЗначения атрибута "SKIN"):

[
    "COMBINATION 1":[
     {
       "COLLECTION": "Vertigo",
       "WEAPON": "SG 553",
       "SKIN": "Tornado",
       "GRADE": "Consumer Grade"
     },
     {
       "COLLECTION": "Assault",
       "WEAPON": "UMP-45",
       "SKIN": "Caramel",
       "GRADE": "Consumer Grade"
     },
     {
       "COLLECTION": "Assault",
       "WEAPON": "Five-SeveN",
       "SKIN": "Candy Apple ",
       "GRADE": "Industrial Grade"
     },...
    ],

    "COMBINATION 2":[
    {
       "COLLECTION": "Assault",
       "WEAPON": "Five-SeveN",
       "SKIN": "Candy Apple ",
       "GRADE": "Industrial Grade"
     },
      {
       "COLLECTION": "Vertigo",
       "WEAPON": "SG 553",
       "SKIN": "Tornado",
       "GRADE": "Consumer Grade"
     },
     {
       "COLLECTION": "Assault",
       "WEAPON": "UMP-45",
       "SKIN": "Caramel",
       "GRADE": "Consumer Grade"
     },...
],...

Также обратите внимание, что один и тот же элемент может появляться в комбинации несколько раз (до 10) и что я работаю с файлом JSON, содержащим около 1500 элементов, поэтомуэффективность является ключевым.Подводя итог, можно сказать, что конечный продукт должен выглядеть примерно так: https://textuploader.com/1du6o

Это тоже своего рода похожая проблема, но менее сложная: Перестановки в JavaScript?

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

1 Ответ

1 голос
/ 17 июня 2019

Хотя не совсем понятно, как определять комбинации так, как вы предлагаете, это может помочь вам в этом.

Создание структуры данных для хранения уникальных элементов для collection, weapon, skin и grade:

// JSON sources.
const sources = [
  {
    "COLLECTION": "Assault",
    "WEAPON": "SG 553",
    "SKIN": "Tornado",
    "GRADE": "Consumer Grade"
  },
  {
    "COLLECTION": "Assault",
    "WEAPON": "UMP-45",
    "SKIN": "Caramel",
    "GRADE": "Consumer Grade"
  },
  {
    "COLLECTION": "Vertigo",
    "WEAPON": "Five-SeveN",
    "SKIN": "Candy Apple ",
    "GRADE": "Industrial Grade"
  },
]

// Create storage for the sources. Use sets to prevent duplicates.
const map = new Map([
  ['COLLECTION', new Set()],
  ['WEAPON', new Set()],
  ['SKIN', new Set()],
  ['GRADE', new Set()]
])

// Load each source into the map.
sources.forEach((source) => {
  Object.keys(source).forEach((key) => {
    const set = map.get(key)
    set.add(source[key])
  })
})

console.log(map)

Выход:

Map {
  'COLLECTION' => Set { 'Assault', 'Vertigo' },
  'WEAPON' => Set { 'SG 553', 'UMP-45', 'Five-SeveN' },
  'SKIN' => Set { 'Tornado', 'Caramel', 'Candy Apple ' },
  'GRADE' => Set { 'Consumer Grade', 'Industrial Grade' } }

Создание всех комбинаций из наборов карты путем итерации с использованием вложенных циклов:

// Store the generated combinations.
const combinations = []

// Generate all combinations.
for (const collection of map.get('COLLECTION')) {
  for (const weapon of map.get('WEAPON')) {
    for (const skin of map.get('SKIN')) {
      for (const grade of map.get('GRADE')) {
        combinations.push({
          'COLLECTION': collection,
          'WEAPON': weapon,
          'SKIN': skin,
          'GRADE': grade,
        })
      }
    }
  }
}

console.log(combinations.length) // 36
...