Steam combinations of entries in javascript array

I am assigned an array of entries in javascript, for example:

var entries = ["cat", "dog", "chicken", "pig"]; 

Now I would like to sort through all the unique pairwise combinations of them. In this example, I would like to see:

 ("cat", "dog"), ("cat", "chicken"), ... 

In other languages, such as scala, it is very simple. You just do

 entries.combinations(2) 

Is there a similar method or function in the library for javascript? Or do I just need to write this in the ugliest way with nested loops?

+5
source share
6 answers

I don’t know how much I know. I think you should stick with nested loops.

A similar question is asked here: Output each combination of an array of numbers using javascript , maybe you can find the answer there.

+2
source
 var arr = ["cat","dog","chicken","pig"].map(function(item,i,arr) { return arr.map(function(_item) { if( item != _item) return [item, _item];}); }); 

This will return the expected results. There are warnings, it does not work in older browsers without padding.

Also, the duplicate value is "undefined" instead of 4 arrays of 3. I am sure there is a more elegant way to handle this.

Array.prototype.map () - MDN

edit

this will give you the correct pairing combinations.

 var arr = ["cat","dog","chicken","pig"].map(function(item,i,arr) { var tmp = arr.map(function(_item) { if( item != _item) return [item, _item];}); return tmp.splice(tmp.indexOf(undefined),1), tmp; }); 

Array Splicing Method - MDN

and here is a more readable version of the same code.

 var myArray = ["cat", "dog", "chicken", "pig"]; var pairwise = myArray.map(function(item, index, originalArray) { var tmp = originalArray.map(function(_item) { if (item != _item) { return [item, _item]; } }); tmp.splice(tmp.indexOf(undefined), 1); // because there is now one undefined index we must remove it. return tmp; }); 
+5
source

After considering the question, this answer incorrectly solves the question. The question asks all the combinations, but the function below combines all adjacent even and odd indices of the array.

Here is a couple implementation I used with shorthand

 function pairwise(arr) { return arr.reduce(function(acc, current, index) { var isFirstPair = (index % 2) === 0; if (isFirstPair) { acc.push([current]); } else { lastElement = acc[acc.length - 1]; lastElement.push(current); } return acc; }, []); }; var nums = [1,2,3,4,5,6]; var res = pairwise(nums); res.forEach(function(elem) { console.log(elem); }); 

Returns:

 [ [1, 2] [3, 4] [5, 6] ] 
+1
source

With ES6 syntax, you can use a shorter version of @rlemon's answer :

 ["cat","dog","chicken","pig"].sort().reduce( (acc, item, i, arr) => acc.concat( arr.slice(i + 1).map(_item => [item, _item]) ), []) 

This takes care of undefined s and also outputs only unique combinations, according to the OP question.

0
source

Here is a generic TypeScript implementation (you can get pure JS by removing types):

 // Returns an array of size const sizedArray = (n: number): null[] => Array(n).fill(null); // calls the callback n times const times = (n: number, cb: () => void): void => { while (0 < n--) { cb(); } }; // Fills up the array with the return values of subsequent calls of cb const fillWithCb = <T>(n: number, cb: () => T): T[] => sizedArray(n).map(cb); // Generic to produce pairwise, 3 element wise etc.. const nWise = (n: number): (<T>(array: T[]) => T[][]) => <T>( array: T[] ): T[][] => { const iterators = fillWithCb(n, () => array[Symbol.iterator]()); iterators.forEach((it, index) => times(index, () => it.next())); return fillWithCb(array.length - n + 1, () => iterators.map(it => it.next().value) ); }; // curried nWise with 2 -> pairWise export const pairWise = nWise(2); 
0
source

The most effective and simplest solution can be reduced and chopped. However, if you just want to get the values. You can use a generator.

 // Util class function pairWise(arr) { return { [Symbol.iterator]: function *() { for(let i =0; i< arr.length; i= i+2) yield arr.slice(i, i+2) } } } // How to use it for(ent of pairWise([1,2,3,4,5,6, 7])){ console.log(ent) } // Output /* [ 1, 2 ] [ 3, 4 ] [ 5, 6 ] [ 7 ] */ 
0
source

All Articles