0

I need to create a combination of n array with structure of data like this

var arrayObject = [
{ name: "size", value: "small" },
{ name: "size", value: "medium" },
{ name: "size", value: "large" },
{ name: "color", value: "red" },
{ name: "color", value: "blue" },
{ name: "color", value: "green" }
]

is there any way to set an array that contain combination of the above array?

the expected output is

var result = [
 [{ Name: "size:", Value: "small" }],
 [{ Name: "size:", Value: "medium" }],
 [{ Name: "size:", Value: "large" }],
 [{ Name: "color", Value: "red" }],
 [{ Name: "color:", Value: "green" }],
 [{ Name: "color:", Value: "blue" }],
 [{ Name: "size", Value: "small" },{ Name: "color:", Value: "red" }],
 [{ Name: "size", Value: "small" },{ Name: "color:", Value: "green"}],
 [{ Name: "size", Value: "small" },{ Name: "color:", Value: "blue"}],
 [{ Name: "size", Value: "medium" },{ Name: "color:", Value: "red"}],
 [{ Name: "size", Value: "medium" },{ Name: "color:", Value: "blue"}],
 [{ Name: "size", Value: "medium" },{ Name: "color:", Value: "green"}],
 [{ Name: "size", Value: "large" },{ Name: "color:", Value: "red"}],
 [{ Name: "size", Value: "large" },{ Name: "color:", Value: "blue"}],
 [{ Name: "size", Value: "large" },{ Name: "color:", Value: "green"}],
]

Any help would be much appreciated. thank you

1
  • 3
    Use nested loops to get all the combinations. Commented Jul 24, 2020 at 5:44

2 Answers 2

1

This will do it:

const arrayObject = [
  { name: "size", value: "small" },
  { name: "size", value: "medium" },
  { name: "size", value: "large" },
  { name: "color", value: "red" },
  { name: "color", value: "blue" },
  { name: "color", value: "green" },
];

const sizes = arrayObject.filter((e) => e.name === "size");
const colors = arrayObject.filter((e) => e.name === "color");

const result = sizes.flatMap((size) => colors.map((color) => [size, color]));

const mergedresult = [...arrayObject, ...result];

console.log(JSON.stringify(mergedresult, null, 2));

One caveat, you need a recent JS interpreter to use flatMap (check the compatibility matrix here).

A few thoughts:

  1. The naming of arrayObject is pretty generic. If you control that initial data structure, I would do something like I did to name it semantically, which leads to splitting it.
  2. The output at the end is a merge of the input and the combinations, which seems strange. I'd think you'd want only the combinations, no? Because you can always merge them at any later point, but separating them later is trickier.
Sign up to request clarification or add additional context in comments.

3 Comments

I just put the code in backticks, and it did it automatically.
wow, thank you, this is brilliant way to solve my problem. i didnt even think of using flatmap function. and for naming, i can change it, i only use for example for this question, and i just need a combination of it, which your answer is a best way to solve it. thanks
0

First make separate lists for colors and sizes. Build all possible combinations with multiple forEach loops.

const combinations = (arr) => {
  const output = [];
  const b = { size: [], color: [] };

  arr.forEach(({ name: Name, value: Value }) => {
    output.push({ Name, Value });
    b[Name].push({ Name, Value });
  });

  b.size.forEach((size) =>
    b.color.forEach((color) => output.push([{...size}, {...color}]))
  );
  return output;
};

var arr = [
  { name: "size", value: "small" },
  { name: "size", value: "medium" },
  { name: "size", value: "large" },
  { name: "color", value: "red" },
  { name: "color", value: "blue" },
  { name: "color", value: "green" },
];

console.log(combinations(arr))

const combinations = (arr, includeEmpty = false) => {
  const groups = {};

  arr.forEach(({ name: Name, value: Value }) => {
    if (!groups[Name]) {
      groups[Name] = includeEmpty ? [null] : [];
    }
    groups[Name].push({ Name, Value });
  });

  let output = [[]];
  Object.values(groups).forEach(group => {
    const temp = [];
    group.forEach(item => {
      output.forEach(list => temp.push(item ? list.concat(item) : list));
    });
    // deep copy
    output = JSON.parse(JSON.stringify(temp));
  });
  return output;
};

var arr = [
  { name: "size", value: "small" },
  { name: "size", value: "medium" },
  { name: "size", value: "large" },
  { name: "color", value: "red" },
  { name: "color", value: "blue" },
  { name: "color", value: "green" },
  { name: "shape", value: "circle" },
  { name: "shape", value: "square" },
];

const items = combinations(arr, true);
console.log(items.length);
console.log(items);

2 Comments

thanks for the answer, this one use a different way to archive it, but i wondering what if the array is dynamic like it can goes with 3 or 4 different name? like 'size','colors', 'shape'. do i need to foreach again and again? thank you
@Steven_Febriant, If they are more groups, We can make iterations dynamically. Just updated the answer with generic approach (eg. added 'shape'), Also check with "includeEmpty" param (true or false), incase if you needed for not including empty item.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.