How to get even numbers array to print first instead of odds? - javascript

So I have this function where I've need to take out the evens and odds and put them into separate arrays but I need the evens array to print first rather than the odds.
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
function divider(numbersArray) {
var evensOdds = [[], []];
for (var i = 0; i < numbersArray.length; i++) {
evensOdds[i & 1].push(numbersArray[i]);
}
return evensOdds;
}

If you want to split the number by their even and odd values, instead of using the index (i), determine the sub array to push into using the value - numbersArray[i] % 2.
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
function divider(numbersArray) {
var evensOdds = [[], []];
for (var i = 0; i < numbersArray.length; i++) {
evensOdds[numbersArray[i] % 2].push(numbersArray[i]);
}
return evensOdds;
}
console.log(divider(numbersArray));
If you want to split them by even and odd indexes use (i + 1) % 2 to determine the sub array to push into:
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
function divider(numbersArray) {
var evensOdds = [[], []];
for (var i = 0; i < numbersArray.length; i++) {
evensOdds[(i + 1) % 2].push(numbersArray[i]);
}
return evensOdds;
}
console.log(divider(numbersArray));

Just for fun, a forEach version of the accepted answer.
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
var even_odd = [ [], [] ];
numbersArray.forEach( e => even_odd[e%2].push(e) );
console.log(even_odd);

Related

Start a for loop on specific index and loop for array length

I'm trying to do a for loop on an array and be able to start that loop on a specific index and loop over the array x amount of times.
const array = ['c','d','e','f','g','a','b','c']
I want to loop 8 indexes starting at any index I wish. Example starting at array[4] (g) would return
'g','a','b','c','c','d','e','f'
This is what I've tried so far
const notes = ['c','d','e','f','g','a','b','c']
var res = []
for (var i = 4; i < notes.length; i++) {
res.push(notes[i])
}
console.log(res)
You can use modulo % operator.
const getArray = (array, index) => {
const result = [];
const length = array.length;
for (let i = 0; i < length; i++) {
result.push(array[(index + i) % length]);
}
return result;
};
Simple way.
var notes = ['c','d','e','f','g','a','b','c'];
function looparr(arr, start)
{
var res = [], start = start || 0;
for(var index = start, length=arr.length; index<length; index++)
{
res.push(arr[index]);
index == (arr.length-1) && (index=-1,length=start);
}
return res;
}
console.log(looparr(['c','d','e','f','g','a','b','c'], 0));
console.log(looparr(['c','d','e','f','g','a','b','c'], 2));
console.log(looparr(['c','d','e','f','g','a','b','c'], 4));
console.log(looparr(['c','d','e','f','g','a','b','c']));
Very simple solution below :)
While i < index, remove the first character from the array, store it in a variable and then add it back onto the end of the array.
let array = ['c','d','e','f','g','a','b','c'];
var index = 4;
for(var i = 0; i < index; i++) {
var letter1 = array.shift(i); // Remove from the start of the array
array.push(letter1); // Add the value to the end of the array
}
console.log(array);
Enjoy :)

How to get the product of numbers gotten from combinations of datasets

I have a combinatoric script that's working fine, actually got most of it from the IBM dev website. But I want to be able to not just show the possible combinations, but also extract the numbers on each combination and get the product of the entire numbers. The project am working on mixes numbers (quantity) with strings (codename). So after combining them, i extract the number from each string and get the product of all the numbers in each combination. As shown;
[A2,B4,C5] = 2*4*5 = 40
Here is my javascript code that gets the combination, not to worry, I ran it with a test array of numbers 1-6, without the characters as shown above.
var Util = function() {
};
Util.getCombinations = function(array, size, start, initialStuff, output) {
if (initialStuff.length >= size) {
output.push(initialStuff);
} else {
var i;
for (i = start; i < array.length; ++i) {
Util.getCombinations(array, size, i + 1, initialStuff.concat(array[i]), output);
}
}
}
Util.getAllPossibleCombinations = function(array, size, output) {
Util.getCombinations(array, size, 0, [], output);
}
// Create an array that holds numbers from 1 ... 6.
var array = [];
for (var i = 1; i <= 6; ++i) {
array[i - 1] = i;
}
var output = [];
var resultArray = [];
Util.getAllPossibleCombinations(array, 4, output);
for(var j=0; j<output.length; j++) {
resultArray += output[j] + "=" + "<br />";
}
document.getElementById("test").innerHTML = resultArray;
});
I tried running this code inside the last for loop to get my multiplication, but it's just not executing, i must be doing something wrong. Here is the code;
var inputval = output[j].replace(/[^,.0-9]/g, '');
inputval = inputval.slice(0, -1);
var hoArray = inputval.split(',');
var cunt= hoArray.length;
var ans=1;
for(var m=0; m<cunt; m++)
{
ans *= hoArray[m];
}
Thanks for your assistance in advance.
walk the array then walk the string, then cast and see if it is an integer then tally and sum the product.
let array = ['A20', 'B11', 'C5'];
function getProduct(ar) {
let product = 1;
for (let x of ar) {
let semiProduct = [];
for (let i of x) {
if (Number.isInteger(+i)) {
semiProduct.push(i);
}
}
product *= semiProduct.join('');
}
return product;
}
console.log(getProduct(array))
You could also use a regular expression.
let array = ['A20', 'B11', 'C5'];
function getProduct(ar) {
let product = 1;
for (let x of ar) {
product *= x.match(/\d+/)[0];
}
return product;
}
console.log(getProduct(array))
If you want a way to generate permutations, you can utilize a generator to make things more concise.
let array = ['A20', 'B11', 'C5'];
function* permu(arr, l = arr.length) {
if (l <= 0) yield arr.slice();
else
for (var i = 0; i < l; i++) {
yield* permu(arr, l - 1);
const j = l % 2 ? 0 : i;
[arr[l - 1], arr[j]] = [arr[j], arr[l - 1]];
}
}
console.log(
Array.from(permu(array))
);
When I run that code in the console it throws an error because output[j] is an array [1,2,3,4] and it looks like you're expecting it to be a string. Arrays do not have a replace method in JS.
You should run this:
var count= hoArray.length;
var ans=1;
for(var m=0; m<count; m++)
{
ans *= hoArray[m];
}
And put output[j] instead of hoArray. And don't do any of this:
var inputval = output[j].replace(/[^,.0-9]/g, '');
inputval = inputval.slice(0, -1);
var hoArray = inputval.split(',');

Group items of two in one array

I am trying to push numbers in an array into another array in groups of two.
If I have an array [1,4,3,2]; it should return [[1,4],[3,2]];
var arrayPairSum = function(nums) {
var len = nums.length / 2;
var arr = [];
for(var i = 0; i < len; i ++) {
var newArr = [];
newArr.push(nums[i]);
newArr.push(nums[i + 1]);
arr.push(newArr);
}
console.log(arr); //this should give me [[1,4],[3,2]];
};
arrayPairSum([1,4,3,2]);
can anyone see what I need to do to achieve this? I cannot figure it out.
You can use reduce method to achieve this. reduce method accepts a callback method provided on every item in the array.
In the other words, this method applies a function against an accumulator and each element in the array (from left to right) to reduce it to a single value.
var array=[1,4,3,2,8];
var contor=array.reduce(function(contor,item,i){
if(i%2==0)
contor.push([array[i],array[i+1]].filter(Boolean));
return contor;
},[]);
console.log(contor);
If you really want to iterate over the array, may skip every second index, so i+=2 ( as satpal already pointed out) :
var arrayPairSum = function(nums) {
var len = nums.length - 1;//if nums.length is not even, it would crash as youre doing nums[i+1], so thats why -1
var arr = [];
for (var i = 0; i < len; i += 2) {
var newArr = [];
newArr.push(nums[i]);
newArr.push(nums[i + 1]);
arr.push(newArr);
}
console.log(arr); //this should give me [[1,4],[3,2]];
};
arrayPairSum([1, 4, 3, 2]);
The upper one crops away every non pair at the end. If you want a single [value] at the end, may go with
len=nums.length
And check later before pushing
if(i+1<nums.length) newArr.push(nums[i+1]);
You were pretty close. Simply change the length to nums.length and in the loop increment i by 2.
var arrayPairSum = function(nums) {
var len = nums.length - 1;
var arr = [];
for(var i = 0; i < len; i+=2) {
var newArr = [];
newArr.push(nums[i]);
newArr.push(nums[i + 1]);
arr.push(newArr);
}
console.log(arr); //this should give me [[1,4],[3,2]];
};
arrayPairSum([1,4,3,2]);

I'm only able to return 1 array

I'm trying to take this array and split it into 2 new arrays, evens and odds and return them. When I run the code below I am only getting the odds, why is that? And what can I do to solve it?
Thanks in advance.
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
function divider( arr ) {
var evens = [];
var odds = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 0) {
evens.push(arr[i]);
} else {
odds.push(arr[i]);
}
}
return(evens, odds);
}
divider(numbersArray);
Because JavaScript can only return one value. Ever.
return(evens, odds)
evaluates to the same value as
return odds
due to the comma operator wrapped in grouping parenthesis.
Perhaps returning an array of arrays (or even an object of arrays) is useful..
return [evens, odds]
You should return your results as an array.
return [evens, odds];
And then to access the results:
var evens;
var odds;
var arrayResults = divider(numbersArray);
evens = arrayResults[0];
odds = arrayResults[1];
console.log(evens);
console.log(odds);
In Javascript, you can only return ONE value. So, if you want to return multiples values, to separate them, you can put them in an array or in an object :
return([evens, odds]);
OR
return({evens: evens, odds: odds})
The result of evaluating (evens, odds) is odds, that is returned thus.
This is how comma operator works.
Use the following statement instead:
return { 'evens': evens, 'odds': odds };
As an example:
var v = divider(numberArrays);
v.evens; // get evens this way
v.odds; // get odds this way
You can return only one entity from a function. Its better to wrap your results in single object.
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
function divider( arr ) {
var evens = [];
var odds = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 0) {
evens.push(arr[i]);
} else {
odds.push(arr[i]);
}
}
return {evens:evens, odds:odds};
}
divider(numbersArray);
Es5 doesn't support tuples, You should wrap your return
in an object like here
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
function divider( arr ) {
var evens = [];
var odds = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 0) {
evens.push(arr[i]);
} else {
odds.push(arr[i]);
}
}
return {evens:evens,
odds:odds};
}
divider(numbersArray);
Or in an array as the other aswers show
You could return an object, like this:
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
function divider( arr ) {
var evens = [];
var odds = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 0) {
evens.push(arr[i]);
} else {
odds.push(arr[i]);
}
}
return {evens, odds};
}
divider(numbersArray);

JavaScript - Generating combinations from n arrays with m elements [duplicate]

This question already has answers here:
Cartesian product of multiple arrays in JavaScript
(35 answers)
Closed 1 year ago.
I'm having trouble coming up with code to generate combinations from n number of arrays with m number of elements in them, in JavaScript. I've seen similar questions about this for other languages, but the answers incorporate syntactic or library magic that I'm unsure how to translate.
Consider this data:
[[0,1], [0,1,2,3], [0,1,2]]
3 arrays, with a different number of elements in them. What I want to do is get all combinations by combining an item from each array.
For example:
0,0,0 // item 0 from array 0, item 0 from array 1, item 0 from array 2
0,0,1
0,0,2
0,1,0
0,1,1
0,1,2
0,2,0
0,2,1
0,2,2
And so on.
If the number of arrays were fixed, it would be easy to make a hard coded implementation. But the number of arrays may vary:
[[0,1], [0,1]]
[[0,1,3,4], [0,1], [0], [0,1]]
Any help would be much appreciated.
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.
I suggest a simple recursive generator function:
// JS
function* cartesianIterator(head, ...tail) {
const remainder = tail.length ? cartesianIterator(...tail) : [[]];
for (let r of remainder) for (let h of head) yield [h, ...r];
}
// get values:
const cartesian = items => [...cartesianIterator(items)];
console.log(cartesian(input));
// TS
function* cartesianIterator<T>(items: T[][]): Generator<T[]> {
const remainder = items.length > 1 ? cartesianIterator(items.slice(1)) : [[]];
for (let r of remainder) for (let h of items.at(0)!) yield [h, ...r];
}
// get values:
const cartesian = <T>(items: T[][]) => [...cartesianIterator(items)];
console.log(cartesian(input));
You could take an iterative approach by building sub arrays.
var parts = [[0, 1], [0, 1, 2, 3], [0, 1, 2]],
result = parts.reduce((a, b) => a.reduce((r, v) => r.concat(b.map(w => [].concat(v, w))), []));
console.log(result.map(a => a.join(', ')));
.as-console-wrapper { max-height: 100% !important; top: 0; }
After doing a little research I discovered a previous related question:
Finding All Combinations of JavaScript array values
I've adapted some of the code from there so that it returns an array of arrays containing all of the permutations:
function(arraysToCombine) {
var divisors = [];
for (var i = arraysToCombine.length - 1; i >= 0; i--) {
divisors[i] = divisors[i + 1] ? divisors[i + 1] * arraysToCombine[i + 1].length : 1;
}
function getPermutation(n, arraysToCombine) {
var result = [],
curArray;
for (var i = 0; i < arraysToCombine.length; i++) {
curArray = arraysToCombine[i];
result.push(curArray[Math.floor(n / divisors[i]) % curArray.length]);
}
return result;
}
var numPerms = arraysToCombine[0].length;
for(var i = 1; i < arraysToCombine.length; i++) {
numPerms *= arraysToCombine[i].length;
}
var combinations = [];
for(var i = 0; i < numPerms; i++) {
combinations.push(getPermutation(i, arraysToCombine));
}
return combinations;
}
I've put a working copy at http://jsfiddle.net/7EakX/ that takes the array you gave earlier ([[0,1], [0,1,2,3], [0,1,2]]) and outputs the result to the browser console.
const charSet = [["A", "B"],["C", "D", "E"],["F", "G", "H", "I"]];
console.log(charSet.reduce((a,b)=>a.flatMap(x=>b.map(y=>x+y)),['']))
Just for fun, here's a more functional variant of the solution in my first answer:
function cartesian() {
var r = [], args = Array.from(arguments);
args.reduceRight(function(cont, factor, i) {
return function(arr) {
for (var j=0, l=factor.length; j<l; j++) {
var a = arr.slice(); // clone arr
a[i] = factor[j];
cont(a);
}
};
}, Array.prototype.push.bind(r))(new Array(args.length));
return r;
}
Alternative, for full speed we can dynamically compile our own loops:
function cartesian() {
return (cartesian.cache[arguments.length] || cartesian.compile(arguments.length)).apply(null, arguments);
}
cartesian.cache = [];
cartesian.compile = function compile(n) {
var args = [],
indent = "",
up = "",
down = "";
for (var i=0; i<n; i++) {
var arr = "$"+String.fromCharCode(97+i),
ind = String.fromCharCode(105+i);
args.push(arr);
up += indent+"for (var "+ind+"=0, l"+arr+"="+arr+".length; "+ind+"<l"+arr+"; "+ind+"++) {\n";
down = indent+"}\n"+down;
indent += " ";
up += indent+"arr["+i+"] = "+arr+"["+ind+"];\n";
}
var body = "var res=[],\n arr=[];\n"+up+indent+"res.push(arr.slice());\n"+down+"return res;";
return cartesian.cache[n] = new Function(args, body);
}
var f = function(arr){
if(typeof arr !== 'object'){
return false;
}
arr = arr.filter(function(elem){ return (elem !== null); }); // remove empty elements - make sure length is correct
var len = arr.length;
var nextPerm = function(){ // increase the counter(s)
var i = 0;
while(i < len)
{
arr[i].counter++;
if(arr[i].counter >= arr[i].length){
arr[i].counter = 0;
i++;
}else{
return false;
}
}
return true;
};
var getPerm = function(){ // get the current permutation
var perm_arr = [];
for(var i = 0; i < len; i++)
{
perm_arr.push(arr[i][arr[i].counter]);
}
return perm_arr;
};
var new_arr = [];
for(var i = 0; i < len; i++) // set up a counter property inside the arrays
{
arr[i].counter = 0;
}
while(true)
{
new_arr.push(getPerm()); // add current permutation to the new array
if(nextPerm() === true){ // get next permutation, if returns true, we got them all
break;
}
}
return new_arr;
};
Here's another way of doing it. I treat the indices of all of the arrays like a number whose digits are all different bases (like time and dates), using the length of the array as the radix.
So, using your first set of data, the first digit is base 2, the second is base 4, and the third is base 3. The counter starts 000, then goes 001, 002, then 010. The digits correspond to indices in the arrays, and since order is preserved, this is no problem.
I have a fiddle with it working here: http://jsfiddle.net/Rykus0/DS9Ea/1/
and here is the code:
// Arbitrary base x number class
var BaseX = function(initRadix){
this.radix = initRadix ? initRadix : 1;
this.value = 0;
this.increment = function(){
return( (this.value = (this.value + 1) % this.radix) === 0);
}
}
function combinations(input){
var output = [], // Array containing the resulting combinations
counters = [], // Array of counters corresponding to our input arrays
remainder = false, // Did adding one cause the previous digit to rollover?
temp; // Holds one combination to be pushed into the output array
// Initialize the counters
for( var i = input.length-1; i >= 0; i-- ){
counters.unshift(new BaseX(input[i].length));
}
// Get all possible combinations
// Loop through until the first counter rolls over
while( !remainder ){
temp = []; // Reset the temporary value collection array
remainder = true; // Always increment the last array counter
// Process each of the arrays
for( i = input.length-1; i >= 0; i-- ){
temp.unshift(input[i][counters[i].value]); // Add this array's value to the result
// If the counter to the right rolled over, increment this one.
if( remainder ){
remainder = counters[i].increment();
}
}
output.push(temp); // Collect the results.
}
return output;
}
// Input is an array of arrays
console.log(combinations([[0,1], [0,1,2,3], [0,1,2]]));
You can use a recursive function to get all combinations
const charSet = [["A", "B"],["C", "D", "E"],["F", "G", "H", "I"]];
let loopOver = (arr, str = '', final = []) => {
if (arr.length > 1) {
arr[0].forEach(v => loopOver(arr.slice(1), str + v, final))
} else {
arr[0].forEach(v => final.push(str + v))
}
return final
}
console.log(loopOver(charSet))
This code can still be shorten using ternary but i prefer the first version for readability 😊
const charSet = [["A", "B"],["C", "D", "E"],["F", "G", "H", "I"]];
let loopOver = (arr, str = '') => arr[0].map(v => arr.length > 1 ? loopOver(arr.slice(1), str + v) : str + v).flat()
console.log(loopOver(charSet))
Another implementation with ES6 recursive style
Array.prototype.cartesian = function(a,...as){
return a ? this.reduce((p,c) => (p.push(...a.cartesian(...as).map(e => as.length ? [c,...e] : [c,e])),p),[])
: this;
};
console.log(JSON.stringify([0,1].cartesian([0,1,2,3], [[0],[1],[2]])));

Categories