English 中文(简体)
如何根据不同的特性,形成各种物体的所有可能的独特组合
原标题:How to generate all possible unique combinations of an array of objects, based on different properties

I have an array of objects and want to create all possible unique combinations based on two keys.

实例 -

[
  { slot:  body , spell:  combat.i , item:  body combat1 },
  { slot:  body , spell:  combat.i , item:  body combat2 },
  { slot:  body , spell:  strength.i , item:  body str1  },
  { slot:  body , spell:  dexterity.i , item:  body dex1  },
  { slot:  legs , spell:  dexterity.i , item:  legs dex1  },
  { slot:  legs , spell:  combat.i , item:  legs combat1  },
  { slot:  legs , spell:  strength.i , item:  legs str1  },
  { slot:  head , spell:  dexterity.i , item:  head dex1  },
  { slot:  head , spell:  combat.i , item:  head combat1  },
  { slot:  head , spell:  strength.i , item:  head str1  },
]

理想产出就好像

[
  [
    { slot:  body , spell:  combat.i , item:  body combat1  },
    { slot:  legs , spell:  dexterity.i , item:  legs dex1  },
    { slot:  head , spell:  strength.i , item:  head str1  },
  ],
  [
    { slot:  body , spell:  combat.i , item:  body combat2  },
    { slot:  legs , spell:  dexterity.i , item:  legs dex1  },
    { slot:  head , spell:  strength.i , item:  head str1  },
  ],
  [
    { slot:  body , spell:  strength.i , item:  body str  },
    { slot:  legs , spell:  dexterity.i , item:  legs dex1  },
    { slot:  head , spell:  combat.i , item:  head combat1  },
  ],
  ...etc
]

因此,最终产品将是每一档次/速记/项目的所有组合,而无需重复(对订单的处理)。

我的第一个想法是,将数据整理成每个时间段的标语,并在其中设置每个结果的阵列。

const generateList = (data, slots, effects) => {
  const matches = {};
  slots.forEach(slot => {
    matches[slot] = {};
    effects.forEach(effect => {
      matches[slot][effect] = data.filter(item => item.slot === slot && item.spell === effect);
    })
  });

  return matches
};

哪类产品产生

{
  body: {
     combat.i : [
      { slot:  body , spell:  combat.i , item:  body combat1  },
      { slot:  body , spell:  combat.i , item:  body combat2  }
    ],
     strength.i : [ { slot:  body , spell:  strength.i , item:  body str1  } ],
     dexterity.i : [ { slot:  body , spell:  dexterity.i , item:  body dex1  } ]
  },
  legs: {
     combat.i : [ { slot:  legs , spell:  combat.i , item:  legs combat1  } ],
     strength.i : [ { slot:  legs , spell:  strength.i , item:  legs str1  } ],
     dexterity.i : [ { slot:  legs , spell:  dexterity.i , item:  legs dex1  } ]
  },
  head: {
     combat.i : [ { slot:  head , spell:  combat.i , item:  head combat1  } ],
     strength.i : [ { slot:  head , spell:  strength.i , item:  head str1  } ],
     dexterity.i : [ { slot:  head , spell:  dexterity.i , item:  head dex1  } ]
  },
]

现在,我很想知道,如何产生所有变化,以创造预期产出,特别是认识到这样做需要扩大规模,使其达到更大的规模。 我知道答案是再入侵,但对于我的生活来说,我sil的头脑可以 figure灭。 感谢任何帮助!

问题回答
const items = [
    { slot:  body , spell:  combat.i , item:  body combat1  },
    { slot:  body , spell:  combat.i , item:  body combat2  },
    // Other items...
];

// Organize the data
let organized = {};
items.forEach(item => {
    if (!organized[item.slot]) {
        organized[item.slot] = {};
    }
    if (!organized[item.slot][item.spell]) {
        organized[item.slot][item.spell] = [];
    }
    organized[item.slot][item.spell].push(item);
});

// Generate combinations
function cartesian(...args) {
    var r = [], max = args.length-1;
    function helper(arr, i) {
        for (var j=0, l=args[i].length; j<l; j++) {
            var a = arr.slice(0); // clone arr
            a.push(args[i][j]);
            if (i==max)
                r.push(a);
            else
                helper(a, i+1);
        }
    }
    helper([], 0);
    return r;
}

let slotCombinations = Object.values(organized).map(spell => Object.values(spell).flat());
let allCombinations = cartesian(...slotCombinations);

// Example to print the first 5 combinations for brevity
allCombinations.slice(0, 5).forEach(combo => console.log(combo));

我不相信这是你想要的:

function generateAllUniqueCombinations(items) {
  // Group items by their slot and then by spell within each slot to facilitate combination generation.
  const groupedBySlotAndSpell = items.reduce((acc, item) => {
    if (!acc[item.slot]) acc[item.slot] = {};
    if (!acc[item.slot][item.spell]) acc[item.slot][item.spell] = [];
    acc[item.slot][item.spell].push(item);
    return acc;
  }, {});

  // Generate all combinations of spells for each slot.
  function findAllSpellCombinations(slots) {
    if (slots.length === 0) return [[]];

    const firstSlotSpells = Object.keys(groupedBySlotAndSpell[slots[0]]);
    const combinationsWithoutFirst = findAllSpellCombinations(slots.slice(1));

    let allCombinations = [];
    firstSlotSpells.forEach((spell) => {
      combinationsWithoutFirst.forEach((combination) => {
        allCombinations.push([{ slot: slots[0], spell }, ...combination]);
      });
    });

    return allCombinations;
  }

  // Convert the slot-spell combinations into item combinations.
  function toItemCombinations(spellCombinations) {
    return spellCombinations.map((combination) =>
      combination.map(
        ({ slot, spell }) =>
          groupedBySlotAndSpell[slot][spell].find((item) => true) // Simply select the first matching item
      )
    );
  }

  const slots = Object.keys(groupedBySlotAndSpell);
  const spellCombinations = findAllSpellCombinations(slots);

  return toItemCombinations(spellCombinations);
}

// Example usage with the provided input array
const items = [
  { slot: "body", spell: "combat.i", item: "body combat1" },
  { slot: "body", spell: "combat.i", item: "body combat2" },
  { slot: "body", spell: "strength.i", item: "body str1" },
  { slot: "body", spell: "dexterity.i", item: "body dex1" },
  { slot: "legs", spell: "dexterity.i", item: "legs dex1" },
  { slot: "legs", spell: "combat.i", item: "legs combat1" },
  { slot: "legs", spell: "strength.i", item: "legs str1" },
  { slot: "head", spell: "dexterity.i", item: "head dex1" },
  { slot: "head", spell: "combat.i", item: "head combat1" },
  { slot: "head", spell: "strength.i", item: "head str1" },
];

const uniqueCombinations = generateAllUniqueCombinations(items);
console.log(uniqueCombinations);

这是我所能做的最好办法,你需要自己进行研究,以适应你期望的结果。

const items = [
  { slot: "body", spell: "combat.i", item: "body combat1" },
  { slot: "body", spell: "combat.i", item: "body combat2" },
  { slot: "body", spell: "strength.i", item: "body str1" },
  { slot: "body", spell: "dexterity.i", item: "body dex1" },
  { slot: "legs", spell: "dexterity.i", item: "legs dex1" },
  { slot: "legs", spell: "combat.i", item: "legs combat1" },
  { slot: "legs", spell: "strength.i", item: "legs str1" },
  { slot: "head", spell: "dexterity.i", item: "head dex1" },
  { slot: "head", spell: "combat.i", item: "head combat1" },
  { slot: "head", spell: "strength.i", item: "head str1" },
  // Add more items for up to 8 slots/spells if needed
];

function groupItemsBySlot(items) {
  return items.reduce((acc, item) => {
    acc[item.slot] = acc[item.slot] || [];
    acc[item.slot].push(item);
    return acc;
  }, {});
}

function generateCombinations(
  groupedItems,
  currentSlotIndex = 0,
  currentCombination = [],
  usedSpells = new Set(),
  allCombinations = []
) {
  const slots = Object.keys(groupedItems);
  if (currentSlotIndex === slots.length) {
    // Base case: all slots processed
    allCombinations.push([...currentCombination]);
    return;
  }

  const currentSlot = slots[currentSlotIndex];
  groupedItems[currentSlot].forEach((item) => {
    if (!usedSpells.has(item.spell)) {
      // Check if the spell is not yet used
      usedSpells.add(item.spell); // Mark the spell as used
      generateCombinations(
        groupedItems,
        currentSlotIndex + 1,
        [...currentCombination, item],
        new Set(usedSpells),
        allCombinations
      );
      usedSpells.delete(item.spell); // Unmark the spell for the next iteration
    }
  });

  if (currentSlotIndex === 0) {
    // Return the result only after the first call completes
    return allCombinations;
  }
}

const groupedItems = groupItemsBySlot(items);
const uniqueCombinations = generateCombinations(groupedItems);
console.log(uniqueCombinations);

Keep it short and simple:

function getTriples(items) {
  const result = [];
  for (const [i, firstItem] of items.entries()) {
    for (const [j, secondItem] of items.entries()) {
      for (const [k, thirdItem] of items.entries()) {
        if (i < j && j < k &&
            firstItem.slot != secondItem.slot && firstItem.slot != thirdItem.slot && secondItem.slot != thirdItem.slot &&
            firstItem.spell != secondItem.spell && firstItem.spell != thirdItem.spell && secondItem.spell != thirdItem.spell
        ) {
          result.push([firstItem, secondItem, thirdItem])
        }
      }
    }
  }
  return result;
}

document.body.textContent = JSON.stringify(getTriples([
  { slot:  body , spell:  combat.i , item:  body combat1 },
  { slot:  body , spell:  combat.i , item:  body combat2 },
  { slot:  body , spell:  strength.i , item:  body str1  },
  { slot:  body , spell:  dexterity.i , item:  body dex1  },
  { slot:  legs , spell:  dexterity.i , item:  legs dex1  },
  { slot:  legs , spell:  combat.i , item:  legs combat1  },
  { slot:  legs , spell:  strength.i , item:  legs str1  },
  { slot:  head , spell:  dexterity.i , item:  head dex1  },
  { slot:  head , spell:  combat.i , item:  head combat1  },
  { slot:  head , spell:  strength.i , item:  head str1  },
]), null, 4);
document.body.style = "white-space: pre; font-family: monospace";

You need to organize the data by slot first, and then by spell within each slot is a good start. After organizing the data, you can generate the combinations.

# Example input
items = [
    { slot :  body ,  spell :  combat.i ,  item :  body combat1 },
    { slot :  body ,  spell :  combat.i ,  item :  body combat2 },
    { slot :  body ,  spell :  strength.i ,  item :  body str1 },
    { slot :  body ,  spell :  dexterity.i ,  item :  body dex1 },
    { slot :  legs ,  spell :  dexterity.i ,  item :  legs dex1 },
    { slot :  legs ,  spell :  combat.i ,  item :  legs combat1 },
    { slot :  legs ,  spell :  strength.i ,  item :  legs str1 },
    { slot :  head ,  spell :  dexterity.i ,  item :  head dex1 },
    { slot :  head ,  spell :  combat.i ,  item :  head combat1 },
    { slot :  head ,  spell :  strength.i ,  item :  head str1 },
]

# Step 1: Organize the data
organized = {}
for item in items:
    slot = item[ slot ]
    spell = item[ spell ]
    if slot not in organized:
        organized[slot] = {}
    if spell not in organized[slot]:
        organized[slot][spell] = []
    organized[slot][spell].append(item)

# Step 2: Generate combinations
# Convert each slot s spells into a list of items
slot_combinations = [list(spell.values()) for spell in organized.values()]
# Generate all combinations using product
all_combinations = list(product(*[item for sublist in slot_combinations for item in sublist]))

# Convert from tuple back to list format for the final output
final_combinations = [[item for item in combo] for combo in all_combinations]

# Example to print the first 5 combinations for brevity
for combo in final_combinations[:5]:
    print(combo)




相关问题
selected text in iframe

How to get a selected text inside a iframe. I my page i m having a iframe which is editable true. So how can i get the selected text in that iframe.

How to fire event handlers on the link using javascript

I would like to click a link in my page using javascript. I would like to Fire event handlers on the link without navigating. How can this be done? This has to work both in firefox and Internet ...

How to Add script codes before the </body> tag ASP.NET

Heres the problem, In Masterpage, the google analytics code were pasted before the end of body tag. In ASPX page, I need to generate a script (google addItem tracker) using codebehind ClientScript ...

Clipboard access using Javascript - sans Flash?

Is there a reliable way to access the client machine s clipboard using Javascript? I continue to run into permissions issues when attempting to do this. How does Google Docs do this? Do they use ...

javascript debugging question

I have a large javascript which I didn t write but I need to use it and I m slowely going trough it trying to figure out what does it do and how, I m using alert to print out what it does but now I ...

Parsing date like twitter

I ve made a little forum and I want parse the date on newest posts like twitter, you know "posted 40 minutes ago ","posted 1 hour ago"... What s the best way ? Thanx.

热门标签