lodash : how to loop with between a start value and end value - javascript

I've a for loop in javascript shown below. How to convert it to lodash for loop?
In such scenarios using lodash is advantageous over javascript for loop?
I've not used lodash much. Hence please advice.
for (var start = b, i = 0; start < end; ++i, ++start) {
// code goes here
}

You can use lodash range
https://lodash.com/docs/4.17.4#range
_.range(5, 10).forEach((current, index, range) => {
console.log(current, index, range)
})
// 5, 0, [5, 6, 7, 8, 9, 10]
// 6, 1, [5, 6, 7, 8, 9, 10]
// 7, 2, [5, 6, 7, 8, 9, 10]
// 8, 3, [5, 6, 7, 8, 9, 10]
// 9, 4, [5, 6, 7, 8, 9, 10]
// 10, 5, [5, 6, 7, 8, 9, 10]

I will imagine that b = 3 and end = 10 if I run your code and print the variables here is what I will get:
var b = 3;
var end = 10;
for (var start = b, i = 0; start < end; ++i, ++start) {
console.log(start, i);
}
> 3 0
> 4 1
> 5 2
> 6 3
> 7 4
> 8 5
> 9 6
To perform this with lodash (or underscore) I will first generate an array with range then iterate over it and gets the index on each iteration.
Here is the result
var b = 3;
var end = 10;
// this will generate an array [ 3, 4, 5, 6, 7, 8, 9 ]
var array = _.range(b, end);
// now I iterate over it
_.each(array, function (value, key) {
console.log(value, key);
});
And you will get the same result. The complexity is the same as the previous one (so no performance issue).

It seems there is no lodash way for writing loose for loops (those not iterating over a collection), but here is a simplified version of it:
for (var i = 0; i < end - b; i++) {
var start = i + b;
// code goes here
}

Related

How do I Replace the elements in the Array and assign it zero in javascript?

Write a function squareWave(arr) that takes in the following array: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], and starts replacing the numbers, one by one, with zeroes, until it reaches a multiple of 5. From that point onwards, start replacing the numbers with 1s, until you reach the next multiple of 5.
Then, from that point onwards, start replacing with 0s again, then 1s again,and so on until you reach the end of the array.
My code is not working Anybody can help me?
let input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18];
function squareWave(arr) {
let zeros = true;
let output = [];
for (let i = 0; i < arr.length; i++) {
if (arr[i] % 5) {
arr[i] = 0;
} else if (arr[i] !== 5) {
arr[i] = 1;
}
}
console.log(arr)
}
Output should be=[0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1]
You are not keeping track if the current entry should be a 0 or 1. Also, you are not using variables zeros and output
Instead of a boolean, you can keep a 0 or 1 in the variable zeros and flip the value when the mod of 5 equals zero.
if (arr[i] % 5 === 0) {
Then for every iteration write the value of zeros
let input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18];
function squareWave(arr) {
let zeros = 0;
let output = [];
for (let i = 0; i < arr.length; i++) {
if (arr[i] % 5 === 0) {
zeros = 1 - zeros
}
output[i] = zeros;
}
return output;
}
console.log(squareWave(input));
Or in short:
let input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18];
let res = input.map(i => Math.abs(Math.floor(i / 5) % 2))
console.log(res)
You can use Array's map function.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
let control = 0;
const list = input.map(value => {
if (value % 5 === 0) {
control = control === 0 ? 1 : 0;
}
return control;
});
console.log(list);
As this is clearly a homework question, I won't give you the answer, but suggest your next steps. You actually almost have the idea of the answer, but you didn't actually implement it.
I'm assuming your current code output looks like [0, 0, 0, 0, 1, 0, 0, 0, 0, 1, ...]
At the beginning of your code you have a boolean variable called zeros. What do you think this boolean is for, and why haven't you used it in your loop?
So your current code is outputting 1 when the value is a multiple of 5, but then it forgets immediately after. How might you fix that?
To replace an element in an array:
Use the indexOf() method to get the index of the element.
Use bracket notation to change the value of the element at the specific index.
The value of the array element will get updated in place.
const arr = ['a', 'b', 'c'];
const index = arr.indexOf('a'); // it will give you 0
if (index !== -1) {
arr[index] = 'z';
}
console.log(arr); // it will give you ['z', 'b', 'c']

Loop backwards Javascript Array

I would like to loop backwards in a array in javascript and then get the index of each element in the array for example if a array has 10 elements and is looped backwards it would log 9, 8, 7, 6, 5, 4, 3, 2, 1, 0. for some werid reason i am getting a bunch of negaitive -1s and im confused why it wont just return the index properly.
here is the code
//Arrays I would like to pass into the function
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
const invalid1 = [4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5];
function validateCred(arr) {
let sum = 0;
for (let i = arr.length - 1; i >= 0; i--) {
console.log(arr.indexOf(i));
}
}
console.log(validateCred(valid1));
why -1s?
It is because of arr.indexOf(i) when the loop starts i=15 so:
arr.indexOf(15) will return -1 because you don't have a 15 in your array.
next i=14 same as above.
.
.
.
i=9 then it will find the element at index 3.
As UnholySheep explains above, Array.indexOf(i) gives you the index of the first occurrence of the value represented by i in the array. Here is some code to help you debug:
function validateCred(arr) {
let sum = 0
for (let i = arr.length - 1; i >= 0; i--) {
console.log(i) // log the index
console.log(arr[i]) // log the value
}
}

What is the difference between these two chunks of code?

Can someone please help me understand the differences between these two programs? I was doing this RallyCoding Prep problem and wrote the first program (and it failed). Then I checked what others did to try and understand but it seems to me that the two programs do basically the same thing, written differently. Can someone help me understand why mine fails and the second program works?
Link to problem: https://www.rallycoding.com/problems/205
--My code--
let k = 16;
let length = Math.sqrt(k);
let height = length;
let arr = []
for(let i = 0; i < length; i++){
let row = [];
for(let x = 1; x <= k; x++){
row.push(x);
}
arr.push(row);
}
console.log(arr)
--Their code--
let k = 16
let c = 1;
const r = Math.sqrt(k);
const result = [];
while(c <= k) {
const block = [];
for (let i = 1; i <= r; i++) {
block.push(c);
c++;
}
result.push(block);
}
console.log(result)
I'm certain I'm missing something very obvious. I hope someone can help me understand this. Thank you!
Since the value of k = 16, the inner loop runs 16 times. So, the result produced by your code is
[
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
]
And the result produced by their code is
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16]
]
So, you can make these changes in your code to get the desired result.
let k = 16;
let length = Math.sqrt(k);
let height = length;
let arr = []
for(let i = 0; i < length; i++){
let row = [];
for(let x = 1; x <= length; x++){
row.push(x + i * length);
}
arr.push(row);
}
You code produces data like this: [[1, 2, 3], [1, 2, 3], ...]
(Each sub-array starts with 1)
You need to produce: [[1, 2, 3], [4, 5, 6], ...]
(Each sub array continues the sequence of the previous one)
the nested forloop you created loop over 16 times
for(let x = 1; x <= k; x++){ row.push(x); }
because K=16 so it will provide an array with 16 element.
the forloop keep runing intel it finish the job.but in the correction they use a "while" loop because The 'while' loop used only when the number of iteration are not exactly known.the are some diff between the two.
Here's a link you can find more

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

Why my push function is not working when I am inserting the value in same array [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
var myNums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var Remve = [];
var i;
for(i=0;i<myNums.length;i++){
if(myNums[i] % 3 == 0){
Remve.push(myNums[i])
}else{
myNums.push(myNums[i])
}
}
document.write(myNums);
document.write(Remve);
Why is my push function not working when I am inserting the value in the same array?
When I am inserting in another array it works.
Dissecting the relevant parts of your code:
// Allocate an array containing three values that will match: [3, 6, 9]
var myNums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Get the length of myNums *every iteration*
for (i = 0; i < myNums.length; i++) {
if (myNums[i] % 3 == 0) {
...
} else {
// Append the value to myNums if it is evenly divisible by three
myNums.push(myNums[i])
}
}
This will hit an infinite loop.
On each iteration, myNums will look like:
[_1_, 2, 3, 4, 5, 6, 7, 8, 9, 10] // append 1
[1, _2_, 3, 4, 5, 6, 7, 8, 9, 10, 1] // append 2
[1, 2, _3_, 4, 5, 6, 7, 8, 9, 10, 1, 2]
[1, 2, 3, _4_, 5, 6, 7, 8, 9, 10, 1, 2] // append 4
[1, 2, 3, 4, _5_, 6, 7, 8, 9, 10, 1, 2, 4] // append 5
... and so on
Once you've hit the end of the collection, every iteration will append yet another value to the very end.
You can solve this pretty easily, if you don't want to hit the appended items:
var myNums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var Remve = [];
var i;
var l = myNums.length;
for (i = 0; i < l; i++) {
if (myNums[i] % 3 == 0) {
Remve.push(myNums[i])
} else {
myNums.push(myNums[i])
}
}
document.write(myNums);
document.write(Remve);
By caching the length first, you won't enter the infinite loop.
You can also push the undivisible items into a different array instead of onto the end of the current one, which will solve the problem equally well.
A) You are constantly checking myNums.length, while inserting values into it.
B) It IS working, as you can see the same values appearing in myNums over and over again. But this is an infinite loop.
C) Console.log(Rmve); shows that you are indeed selecting for numbers divisible by 3.
Your current code is generating an infinite loop, your exit condition is never met.
Notice that myNums.length is constantly increased since you're adding new elements inside loop.
You should get array length before start iterating
var myNums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var Remve = [];
var i;
var arrayLength = myNums.length; // get length BEFORE starting for loop
for(i=0; i < arrayLength; i++){
if(myNums[i] % 3 == 0){
Remve.push(myNums[i])
}else{
myNums.push(myNums[i])
}
}
alert(myNums);
alert(Remve);
It is running in an infinite loop. You are pushing value in a same array so the array length keeps on increasing and it will never end.
var myNums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var Remve = [];
var i;
for(i=0;i<myNums.length;i++){
if(myNums[i] % 3 == 0){
Remve.push(myNums[i])
}else{
myNums.push(myNums[i]) //problematic line
}
}
You didn't say what you meant by "not working," and I'm not sure what you're trying to do, but I saw a problem. The loop was going off of the length of the array, which was changing each time the array ran after the 9th iteration, causing an infinite loop. Saving that in a static variable fixed this:
var myNums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var Remve = [];
var i;
var myNumLength = myNums.length;
for(i=0;i<myNumLength;i++){
if(myNums[i] % 3 == 0){
Remve.push(myNums[i])
}else{
myNums.push(myNums[i])
}
}
document.write(myNums);
document.write('<br>');
document.write(Remve);
Update: new code:
var originalNums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var newNums = [];
var removedNums = [];
var i;
var myNumLength = originalNums.length;
for(i=0;i<myNumLength;i++){
if(originalNums[i] % 3 == 0){
removedNums.push(originalNums[i])
}else{
newNums.push(originalNums[i])
}
}
document.write(newNums);
document.write('<br>');
document.write(removedNums);
Update again
var myNums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var removedNums = [];
var i;
var myNumLength = myNums.length;
for(i=0;i<myNumLength;i++){
if(myNums[i] % 3 == 0){
removedNums.push(myNums[i]);
myNums.splice(i, 1);
i--;
}
}
document.write(myNums);
document.write('<br>');
document.write(removedNums);
Use a separate array (myNumsArr) to store the values instead of myNums. Your current code will result in infinite loop.
var myNums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var myNumsArr = [];
var Remve = [];
var i;
for(i=0;i<myNums.length;i++){
if(myNums[i] % 3 == 0){
Remve.push(myNums[i])
}else{
myNumsArr.push(myNums[i])
}
}
myNums = myNums.concat(myNumsArr);

Categories

Resources