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>
Cartesian product of 2 arrays
You don't need jquery for this:
var customerArray = [[10,'A'],[11,'B']];
var debtorArray = [[88,'W'],[99,'X']];
var customerDebtorMatrix = [];
for (var i = 0; i < customerArray.length; i++) {
for (var l = 0; l < debtorArray.length; l++) {
customerDebtorMatrix.push(customerArray[i].concat(debtorArray[l]));
}
}
customerDebtorMatrix
will be
[ [ 10, 'A', 88, 'W' ],
[ 10, 'A', 99, 'X' ],
[ 11, 'B', 88, 'W' ],
[ 11, 'B', 99, 'X' ] ]
Cartesian product on multiple array of objects in javascript
Instead of using an array to push to, you want to merge the objects:
function cartesianProductOf() {
return Array.prototype.reduce.call(arguments, function(a, b) {
var ret = [];
a.forEach(function(a_el) {
b.forEach(function(b_el) {
ret.push(Object.assign({}, a_el, b_el));
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
});
});
return ret;
}, [{}]);
// ^^
}
If you don't want to use Object.assign
or it's polyfill, the equivalent would be
var r = {};
for (var p in a_el)
r[p] = a_el[p];
for (var p in b_el)
r[p] = b_el[p];
ret.push(r);
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 combine two arrays as a cartesian product?
You can use two for-loops:
var array1 = [1,2,3,4,5];
var array2 = ["one","two","three","four","five"];
var array3 = [];
for (var i = 0; i < array1.length; i++) {
for (var j = 0; j < array2.length; j++) {
array3.push(array2[j] + ' ' + array1[i]);
}
}
console.log(array3);
Cartesian product for arrays in 2Darray
While you are asking about a function call with parameters (which works) and with an array (which does not work), you could insert a check, if arguments.length
is equal to one, and then take the first element of arguments
as value for reducing.
return Array.prototype.reduce.call(arguments.length === 1
? arguments[0]
: arguments, function(a, b) {
// ...
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.
Related Topics
Why Does a Regexp With Global Flag Give Wrong Results
How to Access the Contents of an Iframe With JavaScript/Jquery
Validate Decimal Numbers in JavaScript - Isnumeric()
JavaScript Equivalent to Printf/String.Format
What Is the Reason to Use the 'New' Keyword At Derived.Prototype = New Base
What Is the Use of the JavaScript 'Bind' Method
What Does 'Return' Keyword Mean Inside 'Foreach' Function
What's the Difference Between '$(This)' and 'This'
How to Check If an Element Is Hidden in Jquery
Parsing a String to a Date in JavaScript
Why Is Settimeout(Fn, 0) Sometimes Useful
How to Execute a JavaScript Function When I Have Its Name as a String
What Characters Are Valid For JavaScript Variable Names
How to Get Image Size (Height & Width) Using JavaScript
How to Detect Page Zoom Level in All Modern Browsers