Control Flow and Iteration in Javascript - javascript

I need to iterate through the array and multiply a number by 10 if it is greater than or equal to 5. Here is the code:
const timesTenIfOverFive = [23, 9, 11, 2, 10, 6];
for (let i = 0; i < timesTenIfOverFive.length; i++) {
if (i >= 5) {
console.log(timesTenIfOverFive[i] * 10);
} else {
console.log(timesTenIfOverFive[i]);
}
}
console.log(timesTenIfOverFive);
// -> should print [230, 90, 110, 2, 100, 60]
Thanks.

You need to access the element and change it.
const timesTenIfOverFive = [23, 9, 11, 2, 10, 6];
for (let i = 0; i < timesTenIfOverFive.length; i++) {
if(timesTenIfOverFive[i]>=5){
timesTenIfOverFive[i]=timesTenIfOverFive[i]*10;
}
}
console.log(timesTenIfOverFive);
Also since you are mutating the array, i recommend using var or let for that and not const as follows:
var timesTenIfOverFive = [23, 9, 11, 2, 10, 6];
var res = timesTenIfOverFive.map(x=> x>=5?x*10:x);
console.log(res);

Use Array.prototype.map() to create a new Array by mapping over an existing one
const arr = [23, 9, 11, 2, 10, 6];
const timesTenIfOverFive = arr.map(n => n>=5 ? n*10 : n );
console.log(timesTenIfOverFive)
// -> should print [230, 90, 110, 2, 100, 60]
In short, the ?: Ternary Operator does :
n >= 5 ? // is n greater or equal 5 ?
n * 10 : // if true return the multiplication by 10
n // else return the n
For a reusable function:
const timesTenIfOverFive = arr => arr.map(n => n>=5 ? n*10 : n );
console.log(timesTenIfOverFive([23, 9, 11, 2, 10, 6]))
// -> should print [230, 90, 110, 2, 100, 60]

Related

Find the smallest missing positive int in array in js

How do I find the smallest missing positive integer from an array of integers in js? I didn't find an answer to my question, all I found was in other languages.
Here's an example array:
[-2, 6, 4, 5, 7, -1, 1, 3, 6, -2, 9, 10, 2, 2]
The result should be 8.
You could take an object of seen values and a min variable for keeping track of the next minimum value.
const
data = [-2, 6, 4, 5, 7, -1, 1, 3, 6, -2, 9, 10, 2, 2],
ref = {};
let min = 1;
for (const value of data) {
if (value < min) continue;
ref[value] = true;
while (ref[min]) min++;
}
console.log(min);
You could create an array of positive integer (in this example integers has values from 0 to 10), then use Math.min on integers array filtered with initial array (that was filtered taking only positive numbers):
let integers = Array.from(Array(11).keys());
let arr = [-2, 6, 4, 5, 7, -1, 1, 3, 6, -2, 9, 10, 2, 2];
console.log(Math.min(...integers.filter(x => x > 0 && !arr.filter(x => x > 0).includes(x))));
You can do like below to avoid multiple loops.
Simplest solution is when numbers from 1-10, sum of all number will 55 using this formula (n * (n + 1)) / 2;.
the missing number will be 55-(sum of remaining numbers).
const list = [-2, 6, 4, 5, 7, -1, 1, 3, 6, -2, 9, 10, 2, 2];
const missing = (list) => {
let sum = 0;
let max = 0;
let ref = {};
for (let i = 0; i < list.length; i++) {
const ele = list[i];
if (ele > 0 && !ref[ele]) {
ref[ele] = true;
max = max < ele ? ele : max;
sum += ele;
}
}
const total = (max * (max + 1)) / 2;
return total - sum; // will work if only one missing number
// if multiple missing numbers and find smallest one
// let result = 0;
// for (let i = 1; i <= total - sum; i++) {
// if (!ref[i]) {
// result = i;
// break;
// }
// }
// return result;
};
console.log(missing(list));
I create function for finding the smallest positive.
arr = [-2, 6, 4, 5, 7, -1, 1, 3, 6, -2, 9, 10, 2, 2]
function getSmallestPos(arr) {
pi = [...new Set(
arr.filter(n => n > 0)
.sort((a, b) => a - b ))
];
for (i = 0; i < pi.length; i++) {
if ( pi[i] != (i+1)) {
return (i+1);
}
}
}
console.log(getSmallestPos(arr));
Your questions title contradicts the body of your answer.
To get the smallest positive integer you might try this:
const array = [-2, 6, 4, 5, 7, -1, 1, 3, 6, -2, 9, 10, 2, 2];
// filter array to get just positive values and return the minimum value
const min = Math.min(...array.filter(a => Math.sign(a) !== -1));
console.log(min);
For getting the missing value check this out:
const array = [-2, 6, 4, 5, 7, -1, 1, 3, 6, -2, 9, 10, 2, 2];
const getMissingPositiveInt = (array) => {
// filter array to get just positive values and sort from min to max (0, 1, 4, 5 ...)
const min = array.filter(a => Math.sign(a) !== -1).sort((a,b) => a-b);
for (let i=min[0]; i<array.length; i++) // loop from min over whole array
if (!min.includes(i)) // if array doesnt include index ...
return i; // ... you got your missing value and can return it
}
console.log(getMissingPositiveInt(array));

JS Number of occurences in a sequence is a prime number

I have two arrays (X and Y) and I need to create array Z that contains all elements from array X except those, that are present in array Y p times where p is a prime number.
I am trying to write this in JS.
For Example:
Array X:
[2, 3, 9, 2, 5, 1, 3, 7, 10]
Array Y:
[2, 1, 3, 4, 3, 10, 6, 6, 1, 7, 10, 10, 10]
Array Z:
[2, 9, 2, 5, 7, 10]
So far I have this:
const arrX = [2, 3, 9, 2, 5, 1, 3, 7, 10]
const arrY = [2, 1, 3, 4, 3, 10, 6, 6, 1, 7, 10, 10, 10]
const arrZ = []
const counts = [];
// count number occurrences in arrY
for (const num of arrY) {
counts[num] = counts[num] ? counts[num] + 1 : 1;
}
// check if number is prime
const checkPrime = num => {
for (let i = 2; i < num; i++) if (num % i === 0) return false
return true
}
console.log(counts[10]);
// returns 4
Any hint or help appreciated. Thanks!
You're on the right track. counts should be an object mapping elements in arrY to their number of occurrences. It's easily gotten with reduce.
The prime check needs a minor edit, and the last step is to filter arrX. The filter predicate is just a prime check on the count for that element.
// produce an object who's keys are elements in the array
// and whose values are the number of times each value appears
const count = arr => {
return arr.reduce((acc, n) => {
acc[n] = acc[n] ? acc[n]+1 : 1;
return acc;
}, {})
}
// OP prime check is fine, but should handle the 0,1 and negative cases:
const checkPrime = num => {
for (let i = 2; i < num; i++) if (num % i === 0) return false
return num > 1;
}
// Now just filter with the tools you built...
const arrX = [2, 3, 9, 2, 5, 1, 3, 7, 10]
const arrY = [2, 1, 3, 4, 3, 10, 6, 6, 1, 7, 10, 10, 10]
const counts = count(arrY);
const arrZ = arrX.filter(n => checkPrime(counts[n]));
console.log(arrZ)

How to convert function in recursion [duplicate]

Could you please tell me how to find all subarray with sum equal to number
Example
arr[] = [2, 4, 45, 6, 0, 19]
x = 51
Output: [2,4,45]
Or
arr[] = [1, 11, 100, 1, 0, 200, 3, 2, 1, 280]
x = 280
Output: [280]
I tried like that but not getting correct output
function getSubArray(arr, num) {
var sum = 0,
blank = [];
var bigArr = []
for (var i = 0; i < arr.length; i++) {
sum = arr[i];
if (blank.length === 0) {
blank.push(arr[i]);
}
for (var j = 1; i < arr.length; j++) {
sum += arr[j];
if (sum < num) {
blank.push(arr[j])
} else if (sum > num) {
sum = 0;
blank = [];
break;
} else {
blank.push(arr[j])
bigArr.push(blank);
sum = 0;
blank = [];
}
}
}
return bigArr
}
console.log(getSubArray([1, 3, 6, 11, 1, 5, 4], 4));
for this expected output is
console.log(getSubArray([1, 3, 6, 11, 1, 5,4],4));
output: [1,3]
[4]
expected output
[[1,3], [4]] is my expected output
You could iterate the array and take either the next element or if no element is taken before omit this element.
function getSubset(array, sum) {
function iter(temp, delta, index) {
if (!delta) result.push(temp);
if (index >= array.length) return;
iter(temp.concat(array[index]), delta - array[index], index + 1);
if (!temp.length) iter(temp, delta, index + 1);
}
var result = [];
iter([], sum, 0);
return result;
}
console.log(getSubset([2, 4, 45, 6, 0, 19], 51)); // [2, 4, 45], [45, 6], [45, 6, 0]
console.log(getSubset([1, 11, 100, 1, 0, 200, 3, 2, 1, 280], 280)); // [280]
console.log(getSubset([1, 3, 6, 11, 1, 5, 4], 4)); // [1, 3], [4]
This might not be exactly what's needed - might require tweaking as the logic may be flawed here.
I have commented the code for clarification.
var arr = [1, 3, 6, 11, 1, 5,4]; // Define array
var target = 31; // Define target
// filter the numbers higher than target and sort rest ascending
var withinRange = arr.filter(x => x <= target).sort((a, b) => a - b);
if(arr.reduce((a,b) => a + b) < target) // Check if we have enough numbers to make up that number
throw "The max you can get out of your selection is: " + arr.reduce((a,b) => a + b);
// grab the highest number as a starting point and remove it from our array of numbers
var numbers = [withinRange.pop()];
var toFind = target - getSum(); // get remainder to find
for(var i = withinRange.length - 1; i > -1; i--) // iterate from the top
{
if(toFind == withinRange[i]){ // check if number is exactly what we need
numbers.push(withinRange[i]);
break;
}else if(withinRange[i] <= toFind){ // if number is smaller than what we look for
numbers.push(withinRange[i]);
toFind -= withinRange[i];
}
}
function getSum(){ // sum up our found numbers
if(numbers.length == 0) return 0;
return numbers.reduce((a,b) => a + b);
}
console.log([numbers, [target]]); // print numbers as desired output
console.log(target, getSum()) // print the target and our numbers
function combinations(array) {
return new Array(1 << array.length).fill().map(
(e1,i) => array.filter((e2, j) => i & 1 << j));
}
function add(acc,a) {
return acc + a
}
combinations([2, 4, 45, 6, 0, 19]).filter( subarray => subarray.reduce(add, 0) == 51 )
output
[[2,4,45],[45,6],[2,4,45,0],[45,6,0]]
combinations([1, 11, 100, 1, 0, 200, 3, 2, 1, 280]).filter( subarray => subarray.reduce(add, 0) == 280 )
output
[[280],[0,280]]
It will give all the available case. And I use the test case of #Nina Scholz
const sum = arr => arr.reduce((a,b) => a + b)
function cal(arr, x) {
const rs = []
for (let i = 0; i< arr.length; i++) {
const tmp = []
for (let j=i; j<arr.length; j++ ) {
tmp.push(arr[j])
if(sum(tmp) === x) rs.push([...tmp])
}
}
return rs
}
console.log(cal([1, 11, 100, 1, 0, 200, 3, 2, 1, 280], 280)) // -> [280]
console.log(cal([2, 4, 45, 6, 0, 19], 51)); // -> [2, 4, 45] [45, 6] [45, 6, 0]
console.log(cal([1, 3, 6, 11, 1, 5, 4], 4)); // -> [1,3] [4]
This will try every possible permutation of the array (will stop further permutations once limit is reached)
function test(arr, num) {
// sorting will improve time as larger values will be eliminated first
arr = arr.sort(function(a, b) {
return b - a;
});
var allLists = [];
var start = Date.now();
helper(0, 0, []);
console.log("Ms elapesed: " + (Date.now() - start));
return allLists || "Not found";
function helper(start, total, list) {
var result = [];
// Using for loop is faster because you can start from desired index without using filter, slice, splice ...
for (var index = start; index < arr.length; index++) {
var item = arr[index];
// If the total is too large the path can be skipped alltogether
if (total + item <= num) {
// Check lists if number was not included
var test = helper(index + 1, total, list.concat(result)); // remove for efficiency
total += item;
result.push(item);
//if (total === num) index = arr.length; add for efficiency
}
}
if (total === num) allLists.push(list.concat(result));
}
}
console.log(test([2, 4, 45, 6, 0, 19], 51)); // [2,4,45] [2,4,45,0] [6,45] [6,45,0]
console.log(test([1, 11, 100, 1, 0, 200, 3, 2, 1, 280], 280)); // [280] [280,0]
If you want to make it more efficient and just return one of the resulted array just comment out the recursive call. You can also un-comment the line that exits the loop once the limit has been reached (will skip 0s).
If the question is about finding all subsets (rather than subarrays) with the given cross sum it is also known as the perfect sum problem.
https://www.geeksforgeeks.org/perfect-sum-problem-print-subsets-given-sum/
// A recursive function to print all subsets with the
// help of dp[][]. Vector p[] stores current subset.
function printSubsetsRec(arr, i, sum, p)
{
// If we reached end and sum is non-zero. We print
// p[] only if arr[0] is equal to sun OR dp[0][sum]
// is true.
if (i == 0 && sum != 0 && dp[0][sum])
{
p.push(arr[i]);
console.log(p);
return;
}
// If sum becomes 0
if (i == 0 && sum == 0)
{
console.log(p);
return;
}
// If given sum can be achieved after ignoring
// current element.
if (dp[i-1][sum])
{
// Create a new vector to store path
var b = p.slice(0);
printSubsetsRec(arr, i-1, sum, b);
}
// If given sum can be achieved after considering
// current element.
if (sum >= arr[i] && dp[i-1][sum-arr[i]])
{
p.push(arr[i]);
printSubsetsRec(arr, i-1, sum-arr[i], p);
}
}
// Prints all subsets of arr[0..n-1] with sum 0.
function printAllSubsets(arr, sum)
{
var n = arr.length
if (n == 0 || sum < 0)
return;
// Sum 0 can always be achieved with 0 elements
dp = [];
for (var i=0; i<n; ++i)
{
dp[i] = []
dp[i][0] = true;
}
// Sum arr[0] can be achieved with single element
if (arr[0] <= sum)
dp[0][arr[0]] = true;
// Fill rest of the entries in dp[][]
for (var i = 1; i < n; ++i)
for (var j = 0; j < sum + 1; ++j)
dp[i][j] = (arr[i] <= j) ? dp[i-1][j] ||
dp[i-1][j-arr[i]]
: dp[i - 1][j];
if (dp[n-1][sum] == false)
{
console.log("There are no subsets with sum %d\n", sum);
return;
}
// Now recursively traverse dp[][] to find all
// paths from dp[n-1][sum]
var p = [];
printSubsetsRec(arr, n-1, sum, p);
}
printAllSubsets([1,2,3,4,5], 10);
Solution
'use strict';
function print(arr[], i, j) {
let k = 0;
for (k = i; k <= j; k += 1) {
console.log(arr[k]);
}
}
function findSubArrays(arr[], sum) {
let n = arr.length;
let i;
let j;
let sum_so_far;
for (i = 0; i<n; i+= 1) {
sum_so_far = 0;
for (j = i; j < n; j++) {
sum_so_far += arr[j];
if (sum_so_far === sum) {
print(arr, i, j);
}
}
}
}
I would first loop depending on the size of expected arrays.
After that loop for looking for first part of the array which should be filled with positions that will match the desired number.
For example for x= 4 having arr=[5,4,32,8,2,1,2,2,3,4,4]
It would first take the 4's. Output will start on [ [4], [4], [4], ..... ] for positions 1,9,10 (respectively)
Then go for the arrays resulting sum of 2 elements [ ... [2,2], [2,2],[2,2], [1,3] ...] ( positions 4+6, position 4+7 position6+7 and position 5+8)
You would probably want to use another function to sum and check at this point.
Now will do the same for sum of 3 elements (if any) and so on, having max loop set at number of original array (the resulting number could be the sum of all the elements in the array).
The resulting example would be [ [4], [4], [4], [2,2], [2,2],[2,2], [1,3]]
If the elements would be strictly positive, one could collect such subsequences in a single pass, progressing in a worm/caterpillar-like way: stretching its front in order to grow the sum (when it is bellow the target) and contracting its back in order to lower the sum:
function worm(arr,target){
var ret=[];
var head=0;
var tail=0;
var sum=0;
while(head<arr.length){
while(sum<=target && head<arr.length){
sum+=arr[head++];
if(sum===target)
ret.push(arr.slice(tail,head));
}
while(sum>=target && tail<head){
sum-=arr[tail++];
if(sum===target)
ret.push(arr.slice(tail,head));
}
}
return JSON.stringify(arr)+": "+JSON.stringify(ret);
}
console.log(worm([2, 4, 45, 6, 19], 51));
console.log(worm([1, 11, 100, 1, 200, 3, 2, 1, 280], 280));
console.log(worm([1, 3, 6, 11, 1, 5, 4], 4));
console.log("But it only occasionally finds 0+... / ...+0 sums:");
console.log(worm([2, 4, 45, 6, 0, 19], 51));
console.log(worm([2, 4, 0, 45, 0, 6, 0, 19], 51));
console.log(worm([0, 2, 4, 0, 45, 0, 6, 0, 19], 51));
One way to deal with the problem related to bounding zeroes is to throw such sequences away. This snippet keeps tail and head(-1) on non-zero elements:
function worm(arr,target){
var ret=[];
var head=0;
while(head<arr.length && arr[head]===0)head++;
var tail=head;
var sum=0;
while(head<arr.length){
while(sum<=target && head<arr.length){
while(head<arr.length && arr[head]===0)head++;
sum+=arr[head++];
if(sum===target)
ret.push(arr.slice(tail,head));
}
while(sum>=target && tail<head){
sum-=arr[tail++];
while(tail<head && arr[tail]===0)tail++;
if(sum===target)
ret.push(arr.slice(tail,head));
}
}
return JSON.stringify(arr)+": "+JSON.stringify(ret);
}
console.log(worm([2, 4, 45, 6, 19], 51));
console.log(worm([1, 11, 100, 1, 200, 3, 2, 1, 280], 280));
console.log(worm([1, 3, 6, 11, 1, 5, 4], 4));
console.log(worm([2, 4, 45, 6, 0, 19], 51));
console.log(worm([2, 4, 0, 45, 0, 6, 0, 19], 51));
console.log(worm([0, 2, 4, 0, 45, 0, 6, 0, 19], 51));
console.log(worm([0, 2, 4, 0, 45, 0, 6, 0, 19, 26], 51));
console.log(worm([0, 2, 4, 0, 45, 0, 6, 0, 19, 26, 0], 51));
console.log(worm([1,8,2], 10));
console.log(worm([0,1,0,8,2,0], 10));
console.log(worm([0,8,2,8,0], 10));
console.log(worm([0,8,0,2,0,8,0], 10));
And the code loses all of its remaining beauty if someone actually needs those 0+... / ...+0 sequences, as they have to be generated in a post-processing step:
function worm(arr,target){
var pairs=[];
var head=0;
while(head<arr.length && arr[head]===0)head++;
var tail=head;
var sum=0;
while(head<arr.length){
while(sum<=target && head<arr.length){
while(head<arr.length && arr[head]===0)head++;
sum+=arr[head++];
if(sum===target)
pairs.push([tail,head]);
}
while(sum>=target && tail<head){
sum-=arr[tail++];
while(tail<head && arr[tail]===0)tail++;
if(sum===target)
pairs.push([tail,head]);
}
}
var ret=[];
for([tail,head] of pairs){
(function pre(tail,head){
ret.push(arr.slice(tail,head));
if(tail>0 && arr[tail-1]===0)
pre(tail-1,head);
(function post(tail,head){
if(head<arr.length && arr[head]===0){
ret.push(arr.slice(tail,head+1));
post(tail,head+1);
}
})(tail,head);
})(tail,head);
}
return JSON.stringify(arr)+": "+JSON.stringify(ret);
}
console.log(worm([2, 4, 45, 6, 19], 51));
console.log(worm([1, 11, 100, 1, 200, 3, 2, 1, 280], 280));
console.log(worm([1, 3, 6, 11, 1, 5, 4], 4));
console.log(worm([2, 4, 45, 6, 0, 19], 51));
console.log(worm([2, 4, 0, 45, 0, 6, 0, 19], 51));
console.log(worm([0, 2, 4, 0, 45, 0, 6, 0, 19], 51));
console.log(worm([0, 2, 4, 0, 45, 0, 6, 0, 19, 26], 51));
console.log(worm([0, 2, 4, 0, 45, 0, 6, 0, 19, 26, 0], 51));
console.log(worm([1,8,2], 10));
console.log(worm([0,1,0,8,2,0], 10));
console.log(worm([0,8,2,8,0], 10));
console.log(worm([0,8,0,2,0,8,0], 10));
I think it works (for non-negative elements), but the first one was simpler for sure.
With map and filter
const arr = [2, 4, 45, 6, 0, 19]
let t = 0
const result = arr.map((v,i)=>{
return [v, t += v]
}).filter((v,i)=>v[1]<=51)
console.log(result)

Javascript Generate Multidimensional array of 2 sizes

I cannot figure out the best way to dynamically generate a multidimensional array with 2 different sizes.
We have a UI that requires a row of 4 items, then 3. This pattern would repeat until the content in the array has been spent.
This is essentially what I need to do:
// Convert
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
// to
const rows [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10, 11], [12, 13, 14]];
This is what I currently have, it is only converting the arrays to 4 each.
const buildRows = (arr, length) => arr.reduce((rows, val, i) => (
i % length == 0 ? rows.push([val]) : rows[rows.length-1].push(val)
) && rows, []);
Thank you in advance for the help.
The following solution will mutate (empty) the input array array:
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
let result = [], i = 0;
while(array.length) { // while there still items in array (array is continually getting shrunk untill it is emptied (array.length === 0))
result.push(array.splice(0, i++ % 2? 3: 4)); // cut the first 3 or 4 numbers depending on the index of the cut i (if i is pair, then cut 4, else, cut 3) and then push the cut-out items into the result array
}
console.log(result);
If you don't want to mutate it, then use slice instead of splice, but you'll have to provide the start index of the cut:
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
let result = [], i = 0, next = 0; // next will be the index from which the cut will start
while(next < array.length) { // there is still items to cut
let itemsToCut = i % 2? 3: 4; // determine how many items we are going to cut
result.push(array.slice(next, next + itemsToCut)); // cut the items between next and next + itemsToCut
next += itemsToCut; // increment next by the number of cut-out items so it will point to the next item
i++;
}
console.log(result);
I suggest a more self-documenting generator solution where even & odd row-sizes are not hardcoded but supplied via arguments:
function* reshape(array, ...rows) {
let i = 0;
while (true) for (let row of rows) {
if (i >= array.length) return;
yield array.slice(i, i += row);
}
}
// Example:
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
for (let row of reshape(array, 4, 3)) console.log(row);
A true generator purist would simplify reshape by first introducing a repeat generator:
function* repeat(iterable) {
while (true) yield* iterable;
}
function* reshape(array, ...rows) {
let i = 0;
for (let row of repeat(rows)) {
if (i >= array.length) break;
yield array.slice(i, i += row);
}
}
// Example:
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
for (let row of reshape(array, 4, 3)) console.log(row);
You can achieve that using Array#reduce, a pointer to the last place, and a step variable that alternates between 3 and 4:
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
let last = 0;
let step = 0;
const result = array.reduce((r, num, i) => {
if(i === last + step) { // when the previous sub array is full
r.push([]); // add another sub array
last = i; // mark the start index of the current sub array
step = step === 4 ? 3 : 4; // alternate the step
}
r[r.length - 1].push(num); // push the number to the last sub array
return r;
}, []);
console.log(result);
Straighfoward and easy-to-read solution:
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
const r = [];
let chunk = [];
let l = 4;
array.forEach((el, i) => {
if (chunk.length < l) chunk.push(el);
if (chunk.length === l) {
r.push(chunk); chunk = [];
l = ( l === 4 ) ? 3 : 4;
}
})
console.log(r)
Yet another solution. Clearly everyone is having a good time with this one.
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
function divide(array, idx, num, result)
{
if(array.length <= idx) return result;
result.push(array.slice(idx,idx+num));
return divide(array, idx+num, num === 4 ? 3 : 4, result);
}
console.log(divide(array, 0, 4, []));
We can think of it as slicing elements from the array in a loop. It's just that we need to alternate between 4 and 3 instead of a constant value to slice.
We can parameterize alternating values by passing them in a function instead of hardcoding it in the solution like below:
Use Array##slice and
Just swap current and next like this by using destructuring assignment to achieve the solution.
Sub array sizes(4,3) can be modified outside actual logic or can be passed in a function to have flexible solution.
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
function TransformArray(array, current, next) {
let start = 0,
ans = [];
while (start < array.length - 1) {
ans.push(array.slice(start, start + current));
start += current;
[current, next] = [next, current]; //swap the count of array size
}
return ans;
}
console.log(TransformArray(array, 4, 3));
console.log(TransformArray(array, 3, 3));
Here's kind of a different way of doing this, I'm expanding a bit to allow you to arbitrarily pass array lengths, this allows the PM to change their mind any time and it isn't a big deal.
This could be cleaned up a bit, I wanted to leave it more verbose to make it easier to read.
// Setup the function getting in:
// an array
// first array's length
// second array's length
const arrayParser = (inArr,arr1len,arr2len) => {
// Create a new array.
let outArr = [];
// Basic forEach is basic, we need the value and the index.
inArr.forEach((val,idx) => {
// If the index's modulus of the total of the two array lengths is:
// 0 OR the first array's length
// Push a new empty array.
if (idx%(arr1len+arr2len)===0 || idx%(arr1len+arr2len)===arr1len) {
// Create a new array with the current value
outArr.push([]);
}
// Push the value to the last array in the out multidimensional array
outArr[outArr.length-1].push(val);
});
// You got it.. return the array.
return outArr;
};
// Single Dimensional Array
const singleArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30];
// Parse it.
// Expects:
// A Single Dimensional Array
// Length of the first array
// Length of the second array
console.log(arrayParser(singleArray,10,4));
console.log(arrayParser(singleArray,2,4));
console.log(arrayParser(singleArray,3,4));
console.log(arrayParser(singleArray,4,3));
console.log(arrayParser(singleArray,1,2));
This works, because you know the length of each of the inner arrays, so you don't really need to figure out anything.
Here's a 4,3 set broken out.
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
Push a new array at 0 and 4.
4+3
index total Modulus
0 % 7 = 0 <-- push [], push 1
1 % 7 = 1 <-- push 2
2 % 7 = 2 <-- push 3
3 % 7 = 3 <-- push 4
4 % 7 = 4 <-- push [], push 5
5 % 7 = 5 <-- push 6
6 % 7 = 6 <-- push 7
7 % 7 = 0 <-- push [], push 8
8 % 7 = 1 <-- push 9
9 % 7 = 2 <-- push 10
10 % 7 = 3 <-- push 11
11 % 7 = 4 <-- push [], push 12
12 % 7 = 5 <-- push 13
13 % 7 = 6 <-- push 14
Returns
[[1,2,3,4],[5,6,7],[8,9,10,11],[12,13,14]]
It ain't pretty and as much as I try to write functional code, it's pretty easy with a while loop...
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
const newArray = [];
let i = 0;
while (i < array.length) {
let four = array.slice(i, i + 4)
if (!(four.length > 0)) {
break;
}
newArray.push(four)
i += 4;
let three = array.slice(i, i + 3);
if (!(three.length > 0)){
break;
}
newArray.push(three);
i += 3;
}
return newArray

Split javascript array of numbers into ranges

I have an array such as:
[16, 20, 1, 4, 6, 8, 9, 22, 18, 14, 13, 12]
That I would like split into 6 different arrays based on ranges 1-4, 5-8, 9-12, 13-16, 17-20, 21-24.
What is the simplest way to do this with javascript?
You could use an interval for assigning the numbers to a specific slot.
var array = [16, 20, 1, 4, 6, 8, 9, 22, 18, 14, 13, 12],
interval = 4,
result = array.reduce(function (r, a) {
var slot = Math.floor((a - 1) / interval);
(r[slot] = r[slot] || []).push(a);
return r;
}, []);
console.log(result);
The solution using Array.prototype.filter() function:
var list = [16, 20, 1, 4, 6, 8, 9, 22, 18, 14, 13, 12], i
result = [];
// considering ranges `1-4, 5-8, 9-12, 13-16, 17-20, 21-24`
for (i = 1; i < 24; i+= 4) {
result.push(list.filter(function(d){
return ((i+4 > d) && d >= i); // check if the number between lower and upper bound
}));
}
console.log(result);
Simplest answer:
var numbers = [16, 20, 1, 4, 6, 8, 9, 22, 18, 14, 13, 12];
var array1 = []; // range 1-4
var array2 = []; // range 5-8
for(var i=0; i< numbers.length; i++) {
if(numbers[i]>= 1 && numbers[i] <= 4) {
array1[i] = numbers[i]
} else if(numbers[i]>= 5 && numbers[i] <= 8) {
array2[i] = numbers[i]
}
//... continue for remaining ranges
}

Categories

Resources