Finding All Combinations (Cartesian product) of JavaScript array values and then ordering them
Sort by age and male/female.
let output = ["age 18-24, women", "age 25-34, women", "age 35-44, women", "age 45 or over, women", "age 18-24, men", "age 25-34, men", "age 35-44, men", "age 45 or over, men"]
const getAge = (str) => {
let ageArr = str.match(/(age \d)\w/);
return ageArr?.length ? +ageArr[0].replace("age ", "") : 0;
};
output.sort((a, b) => {
let age1 = getAge(a);
let age2 = getAge(b);
let isFemale1 = a.includes("women");
let isFemale2 = b.includes("women");
if (!isFemale1 && isFemale2) {
return 1
} else if (isFemale1 && !isFemale2) {
return -1
}
return age1 - age2;
});
console.log(output);
Cartesian product of multiple arrays in JavaScript
Here is a functional solution to the problem (without any mutable variable!) using reduce
and flatten
, provided by underscore.js
:
function cartesianProductOf() { return _.reduce(arguments, function(a, b) { return _.flatten(_.map(a, function(x) { return _.map(b, function(y) { return x.concat([y]); }); }), true); }, [ [] ]);}
// [[1,3,"a"],[1,3,"b"],[1,4,"a"],[1,4,"b"],[2,3,"a"],[2,3,"b"],[2,4,"a"],[2,4,"b"]]console.log(cartesianProductOf([1, 2], [3, 4], ['a']));
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore.js"></script>
Finding All Combinations (Cartesian product) of JavaScript array values
This is not permutations, see permutations definitions from Wikipedia.
But you can achieve this with recursion:
var allArrays = [
['a', 'b'],
['c'],
['d', 'e', 'f']
]
function allPossibleCases(arr) {
if (arr.length == 1) {
return arr[0];
} else {
var result = [];
var allCasesOfRest = allPossibleCases(arr.slice(1)); // recur with the rest of array
for (var i = 0; i < allCasesOfRest.length; i++) {
for (var j = 0; j < arr[0].length; j++) {
result.push(arr[0][j] + allCasesOfRest[i]);
}
}
return result;
}
}
console.log(allPossibleCases(allArrays))
Cartesian product (all combinations) in array of multi-dimentonal objects with flexible length
As I promised, I have found a solution of my problem and I'd like to share it with StackOverflow Community.
Pseudo-code:
let array = [
{
field: "original, can be cloned for every combination",
items:
[
{id: 1, quantity: 2},
{id: 2, quantity: 3}
]
}
]
for (let element of array) {
let MethodsCombinations = [];
for await (let forCombinations of element.items.map((item, i) => {
return getMethod(item.id) //get Method for each item)
})) {
MethodsCombinations.push(forCombinations)
}
/* Cartesian product */
let vanilla_CartesianProduct = MethodsCombinations.reduce((a, b) => a.reduce((r, v) => r.concat(b.map(w => [].concat(v, w))), []));
/* Return array of arrays, with objects inside like default array */
/**
* Other logic with two for loops and merging all the combinations and quantities
* with (my own) modified Array.prototype.addItemToArray
*/
}
I am very grateful to this Nina Scholz's answer and her awesome StackOverflow profile with all answers about combinations/permutations and for providing a support.
Generation cartesian product objects from array values
First of all, that's not a problem with permutations
, it's exactly Cartesian product
.
In set
theory (and, usually, in other parts of mathematics), a Cartesian product
is a mathematical operation that returns a set
from multiple sets.
You can achieve that using ES6
features like map and reduce methods.
function cartesianProduct(...arrays) { return [...arrays].reduce((a, b) => a.map(x => b.map(y => x.concat(y))) .reduce((a, b) => a.concat(b), []), [[]]);}console.log(cartesianProduct([1, 2], [3, 4], [5, 6]));
How to generate in Javascript all combinations of items from multiple objects
Update: Fixed the first cartesian
implementation based on suggestion from Mulan.
This is definitely a cartesian product question. The only thing is that you will need to format your input before you call the cartesian product. Here is one version, using a simple, recursive cartesian
function.
const cartesian = ([xs, ...xss]) =>
xs == undefined
? [[]]
: xs .flatMap (x => cartesian (xss) .map (ys => [x, ...ys]))
const combine = (properties) =>
cartesian (properties .map (({name, options}) => options .map (({value}) => ({name, value}))))
const properties = [{name: "Size", options: [ { value: "S" }, { value: "M" }, { value: "L" }, /*...and so on */]}, {name: "Color", options: [ { value: "Red" }, { value: "White" }, { value: "Blue" }, /*...and so on */]}, {name: "Weight", options: [ { value: "1kg" }, { value: "2kg" }, { value: "3kg" }, { value: "4kg"}, ]}, /* .... and so on */]
console .log (JSON .stringify (combine (properties), null, 2))
.as-console-wrapper {max-height: 100% !important; top: 0}
JavaScript - Generating combinations from n arrays with m elements
Here is a quite simple and short one using a recursive helper function:
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;
}
Usage:
cartesian([0,1], [0,1,2,3], [0,1,2]);
To make the function take an array of arrays, just change the signature to function cartesian(args)
instead of using rest parameter syntax.
Related Topics
How to Check If a Checkbox Is Checked
Check/Uncheck Checkbox with JavaScript
How to Get the Scrollbar Position with JavaScript
How to Get Character Array from a String
JavaScript - Get Array of Dates Between 2 Dates
Convert Utc Epoch to Local Date
Render Partial View Using Jquery in ASP.NET MVC
Copy Array Items into Another Array
JavaScript Closures VS. Anonymous Functions
Babel File Is Copied Without Being Transformed
Differencebetween 'New Object()' and Object Literal Notation
Getting Value of Select (Dropdown) Before Change
What Is the Meaning of "$" Sign in JavaScript
Truncate Number to Two Decimal Places Without Rounding
How to Resize Images Proportionally/Keeping the Aspect Ratio