Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 months ago.
Improve this question
The task is to write a function to reverse an array of numbers and print out each number every 2 seconds. Also print the reversed array in the end.
I wrote the following to achieve this, but it is a bad method, since I need to calculate the number of seconds in each setTimeout and also take extra steps to determine whether the for loop has reached the last iteration.
Is there a direct way to pause 2 seconds after each iteration and then print the reversed array in a synchronous way?
const reverseNumbers = (array) => {
const n = array.length;
return new Promise((resolve) => {
let res = [];
for (let i = n - 1; i >= 0; i--) {
setTimeout(() => {
console.log(array[i]);
res.push(array[i]);
if (i === 0) resolve(res);
}, 2000 * (n - i));
}
});
};
const array = [1, 2, 3, 4, 5];
let myPromise = reverseNumbers(array);
myPromise.then((res) => console.log(res));
Is there a better way to return an updated value after setTimeout?
Promisify setTimeout on its own, then use async/await:
function delay(t) {
return new Promise(resolve => {
setTimeout(resolve, t);
});
}
async function reverseNumbers(array) {
const n = array.length;
const res = [];
for (let i = n-1; i >= 0; i--) {
await delay(2000);
console.log(array[i]);
res.push(array[i]);
}
return res;
}
const array = [1, 2, 3, 4, 5];
const myPromise = reverseNumbers(array);
myPromise.then(console.log);
Here is another way of doing it. No idea, whether this is shorter or better, but in any case: it works.
function rev(arr){
let r=arr.slice(0),
intv=setInterval(()=>{
if(r.length) console.log(r.pop());
else {
clearInterval(intv);
console.log(arr.reverse())
}
}, 2000);
}
rev([0,8,15,47,11]);
Related
I have written 2 types of sum functions.
Loop sum
const sum = (n) => {
let sum = 0;
for (let i = 1; i <= n; i++) {
sum += i;
}
return sum;
};
console.time('sum');
console.log(sum(1_00_000));
console.timeEnd('sum');
// Output:
// 5000050000
// sum: 11.172ms
Partitioned sum (Partitioning of the event loop)
const sum = (n, cb) => {
let total = 0;
const help = (i, cb) => {
if (i > n) {
return cb(total);
}
total += i;
setImmediate(help, i + 1, cb);
};
help(0, cb);
};
console.time('sum');
sum(1_00_000, (result) => {
console.log(result);
console.timeEnd('sum');
});
// Output:
// 5000050000
// sum: 1.225s
Now, the Loop sum takes way less time than the Partitioned sum.
But, partitioning and off-loading are the recommended ways of handling computationally intensive tasks as mentioned here: https://nodejs.org/en/docs/guides/dont-block-the-event-loop/#don-t-block-the-event-loop
My question are:
How is partitioning of event loop good for large scale operations?
Am I right here to compare the two using the time taken?
What would be a better metric in this case?
Edit 1: Replaced screenshots with code snippets and output
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 10 months ago.
Improve this question
I found myself a problem. I want to print an array from number 0 to 100.
if the number is divisible by 3, I want to print flip.
if the number is divisible by 5, I want to print flop.
for example the array should be [0,1,2,'flip',4,'flop','flip,........,'flop'].
How to do this in JS?
So far I have done this but it doesn't print the whole array.
function wow() {
var arr = []
for (let i = 0; i <= 100; i++) {
if(i!=0){
if(i%3===0){
i='flip'
arr.push(i)
}
if(i%5===0){
i='flop'
arr.push(i)
}
}
arr.push(i)
}
console.log(arr)
}
wow()
You're changing the variable i within the for loop which you shouldn't be doing. Try using a temp variable for determining what gets pushed to your array.
Also, if a number is divisible by 3 AND 5 then the latter (flop) takes precedent, is that what you expect to happen?
function wow() {
var arr = []
for (let i = 0; i <= 100; i++) {
let temp = i;
if (i != 0) {
if (i % 3 === 0) {
temp = 'flip'
}
if (i % 5 === 0) {
temp = 'flop'
}
}
arr.push(temp)
}
console.log(arr);
}
Here's a bit shorter version...
let arr = Array.from({
length: 101
}, (e, i) => i)
arr.forEach((n, i) => {
Number.isInteger(n / 3) ? arr[i] = 'flip' : null, Number.isInteger(n / 5) ? arr[i] = 'flop' : null
})
console.log(arr)
const dot = (a,b) => x => a(b(x));
const id = x => x;
function flipflop(n){
const f = (N, m) => n % N ? id : x => _ => m + x('');
return dot(f(3, 'flip'), f(5, 'flop')) (id) (n);
}
let arr = Array(101).fill(0).map((_,i)=>flipflop(i));
console.log(arr);
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I'm very new to coding and I've been trying to practice arrays and storing new elements into empty arrays. this code runs, but nothing comes back. what am I doing wrong?
const myArr = [2,2,3,4,4,5]
const evenArray = [];
const oddArray = [];
for (let i=0; i<myArr.length; i++) {
if (myArr[i] % 2 == 0)
myArr.push(evenArray[i])
return evenArray
} if (myArr[i % 2 !== 0]) {
myArr.push(oddArray[i])
}
return oddArray
console.log(evenArray)
There are a lot of problems with your code.
For example:
You are trying to use return out of a function.
You are pushing into myArr, instead of even or odd arrays..
You are also not correctly using the curly braces. Here is how you should do it.
const myArr = [2, 2, 3, 4, 4, 5];
const evenArray = [];
const oddArray = [];
for (let i = 0; i < myArr.length; i++) {
if (myArr[i] % 2 === 0) {
// even
evenArray.push(myArr[i]);
} else {
// odd
oddArray.push(myArr[i]);
}
}
console.log({ evenArray });
console.log({ oddArray });
console.log({ myArr });
.as-console-wrapper { min-height: 100%!important; top: 0; }
Main problems with how you are writing your code:
Return statement not within function
Not using if statements correctly
Here is a solution:
const myArr = [2, 2, 3, 4, 4, 5];
const evenArray = [];
const oddArray = [];
for (let i = 0; i < myArr.length; i++) {
if (myArr[i] % 2 == 0) {
evenArray.push(myArr[i]);
} else {
// We can just use an else statement here because anything thats not even is odd
oddArray.push(myArr[i]);
}
}
console.log(evenArray, oddArray); // Now that the loop has run console.log the results
Note: Stack overflow is not the place to ask questions about the basics of coding! I would recommend checking out freeCodeCamp.org and their YouTube channel because you seem to have problems with the fundamental principals of js.
You dont need return statements. Only save values into new arrays.
const myArr = [2,2,3,4,4,5]
const evenArray = [];
const oddArray = [];
for (var i=0; i < myArr.length; i++) {
if (myArr[i] % 2 == 0) {
evenArray.push(myArr[i]) //push even elements into evenArray
}
if (myArr[i] % 2 !== 0) {
oddArray.push(myArr[i]) //push odd elements into oddArray
}
}
console.log(evenArray) //evenArray will have even numbers
console.log(oddArray) //oddArray will have odd numbers
Please share which programming language you're using.
As per your code it seems you are pushing the empty array value to your myArr array. Try using evenArray.push(myArr[i]) instead of myArr.push(evenArray[i])
Something similar to question Convert ES6 Iterable to Array. But I only want first N items. Is there any built-in for me to do so? Or how can I achieve this more elegantly?
let N = 100;
function *Z() { for (let i = 0; ; i++) yield i; }
// This wont work
// Array.from(Z()).slice(0, N);
// [...Z()].slice(0, N)
// This works, but a built-in may be preferred
let a = [], t = Z(); for (let i = 0; i < N; i++) a.push(t.next().value);
To get the first n values of an iterator, you could use one of:
Array.from({length: n}, function(){ return this.next().value; }, iterator);
Array.from({length: n}, (i => () => i.next().value)(iterator));
To get the iterator of an arbitrary iterable, use:
const iterator = iterable[Symbol.iterator]();
In your case, given a generator function Z:
Array.from({length: 3}, function(){ return this.next().value; }, Z());
If you need this functionality more often, you could create a generator function:
function* take(iterable, length) {
const iterator = iterable[Symbol.iterator]();
while (length-- > 0) yield iterator.next().value;
}
// Example:
const set = new Set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
console.log(...take(set, 3));
There is no built in method to take only a certain number of items from an iterable (ala something like take()). Although your snippet can be somewhat improved with a for of loop, which is specifically meant to work with iterables, eg:
let a = []; let i = 0; for (let x of Z()) { a.push(x); if (++i === N) break; }
Which might be better since your original snippet would continue looping even if there are not N items in the iterable.
A bit shorter and less efficient with .map, and a bit safer with custom function:
function *Z() { for (let i = 0; i < 5; ) yield i++; }
function buffer(t, n = -1, a = [], c) {
while (n-- && (c = t.next(), !c.done)) a.push(c.value); return a; }
const l = console.log, t = Z()
l( [...Array(3)].map(v => t.next().value) )
l( buffer(t) )
how can I achieve this more elegantly?
One possible elegant solution, using iter-ops library:
import {pipe, take} from 'iter-ops';
const i = pipe(
Z(), // your generator result
take(N) // take up to N values
); //=> Iterable<number>
const arr = [...i]; // your resulting array
P.S. I'm the author of the library.
This question already has answers here:
How can I make var a = add(2)(3); //5 work?
(33 answers)
Closed 5 years ago.
I want to implement the function in javascript let say Add that should support bellow formats
add(a,b,c)
add(a)(b)(c)
add(a)(b,c)
add(a,b)(c)
All these should return a+b+c. Is it possible? if so how?
Whenever the function is run collect the arguments object parameters into an array, and check it's length. If the length of the array is 3 or greater sum the first 3 numbers using Array#reduce. If not, return the function.
function add() {
var args = []; // collect the arguments
function innerAdd() {
args.push.apply(args, arguments); // add the arguments to args
// if the length of args is under 3 return innerAdd, if not sum the first 3 numers
return args.length < 3 ? innerAdd : args.slice(0, 3).reduce(function(s, n) {
return s + n;
});
}
return innerAdd.apply(null, arguments); // invoke innerAdd with current arguments
}
var a = 1, b = 2, c = 3;
console.log(add(a,b,c));
console.log(add(a)(b)(c));
console.log(add(a)(b,c));
console.log(add(a,b)(c));
You can do something like
function add(){
let sum = 0;
for(let e of arguments) sum += e;
let ret = add.bind(null, sum);
ret.toString = () => sum;
ret.valueOf = () => sum;
return ret;
}
let x = +add(2, 3)(4)(11)
console.log(x, typeof x);