Steven_Febriant
Steven_Febriant

Reputation: 9

Any way to create a combination of array object with javascript?

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

Upvotes: 0

Views: 1259

Answers (2)

Siva Kondapi Venkata
Siva Kondapi Venkata

Reputation: 11001

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

Upvotes: 0

Josh Wulf
Josh Wulf

Reputation: 4877

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.

Upvotes: 1

Related Questions