All possible combinations with data from JSON file

半城伤御伤魂 提交于 2021-01-27 20:03:14

问题


My goal is to create a part of code that would generate all possible combinations without duplicates (combinations with same elements, no matter what their sequence is) with data from a JSON file. My JSON file looks like this:

[
 {
   "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"
 }, ...
]

Combinations would be generated in the following way:

[
    "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"
     }, ...
    ],...
]

Note that in this case both combinations have the same elements and therefore shouldn't be noted twice. That means that as long as there are elements in a combination that are same to another possible combination (no matter what sequence they are in) it counts as one combination (every combination will have 10 elements, and would be distinct from another based on the "SKIN" attribute values):

[
    "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"
     },...
],...

Also note that the same item can appear in a combination multiple times (up to 10) and that I'm workig with a JSON file of around 1500 elements, so efficiency is key. To sum it up the final product should look something like this: https://textuploader.com/1du6o

This is also a kinda similar problem, but less complex: Permutations in JavaScript?

I've tried to sort this out with bubble sort and such, but haven't succeeded thus far. If you have any ideas how to make this happen I'd love to hear them.


回答1:


Although it's not entirely clear how to determine combinations the way you suggest, this might get you part of the way there.

Create a data structure to store unique elements for collection, weapon, skin, and 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)

Output:

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' } }

Generate all combinations from the map's sets by iterating using nested loops:

// 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


来源:https://stackoverflow.com/questions/56633869/all-possible-combinations-with-data-from-json-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!