Problem Description
I am trying to generate an array using keys() and .map() methods, given a preexisting array with length = arrLength, such that only items at a position that are multiples of step are generated. Here is an example,
const arrLength = 20;
const step = 5;
const newArr = [...Array(arrLength).keys() ].map((i) => i + step);
console.log(newArr) ;
// expected: 0,5,10,15,20
// recieved : 5,6,7,...,24
I am particlarly confused as to how to increment the left hand side variable i in map((i) => ... ).
Restrictions
I want to implement this in one line using the keys method and Array and possibly map, so no for loop.
Things I have tried
I tried the following signatures instead
Array(arrLength).fill().map((_, i) => i+step) ,
Array.from(Array(arrLength), (_, i) => i+step),
Array.from({ length: arrLength }, (_, i) => i+step)
but with no success. I have further tried to find a way to increment the i variable using functional syntax but with no success as wel.
const arrLength = 20;
const step = 5;
const arr = [];
for (let i = 0; i<= arrLength; i+=step){
arr.push(i);
}
console.log(arr);
Or
const arrLength = 20;
const step = 5;
const newArr = [...Array(Math.floor(arrLength/step) + 1).keys() ].map((i) => i * step);
console.log(newArr);
range function work with ES4
Using Array.from can pass an object has property length in it
const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));
console.log(range(0, 20, 5))
Stumbled upon this, and while looking at the answers I came up with this. This just basically creates an array with incrementing numbers, but could be extended easily.
This reduce function generates desired array by taking the index i of given element and then we combine what we already got in the previous recursive step (the a variable) with the incremental value i.
const arr = new Array(52).fill(0).reduce((a,_,i) => [...a, i],[])
Related
Can someome explain to me how New Array, and Array works with this loop? Also, anyone knows if is possible of doing a array and inside this array a function? Because this way of doing seem kinda wrong considering POO and SRP
Here`s the link of the exercise: https://www.codewars.com/kata/569e09850a8e371ab200000b/train/javascript
function preFizz(n) {
let output = new Array();
let num = 1;
while(output.length < n){
output.push(num);
num += 1;
}
return output;
}
Ok, i found the answer thanks to epascarello and Abdennour TOUMI. Here´s the link where of the answer: How to create an array containing 1...N
Basically i was trying to finding more about arrays and loops(In a more pratice way), this codes maked more easier to understand
let demo = (N,f) => {
console.log(
Array.from(Array(N), (_, i) => f(i)),
)
}
Why not use a traditional for-loop? It has declaration, conditional, and increment functionality built right in.
const preFizz = (n) => {
const output = [];
for (let num = 1; num <= n; num++) {
output.push(num);
}
return output;
}
console.log(...preFizz(10));
A more modern version of this would be to declare an array of a specified length and map the indices.
const preFizz = (n) => Array.from({ length: n }).map((_, i) => i + 1);
console.log(...preFizz(10));
I'm looking for something like the built-in Array.prototype.find(), but I want to be able to search starting from a given index, without creating a new shallow copy of range of items from this array.
possibilities:
using Array.prototype.find with no starting index.
using Array.prototype.slice() and then .find. something like arr.slice(startIndedx).find(...). creating shallow copy.
writing my own find implementation using for loop that start looking from given index.
using lodash.find(). but I care about bundle size and lodash is quite heavy. I actually prefer avoiding any kind of third-party packages.
here are some performance test results :
const SIZE = 1000000
const START_I = 800000
const ItemVal = 900000
...
find: average time: 12.1ms
findSlice: average time: 2.48ms
findLodash: average time: 0.26ms
myFind: average time: 0.26ms
surprisingly enough its seems that that native .find performed worse even with starting index 0 :
const SIZE = 1000000
const START_I = 0
const ItemVal = 900000
...
find: average time: 12.61ms
findSlice: average time: 17.51ms
findLodash: average time: 1.93ms
myFind: average time: 2.17ms
for array size 1000000 , starting index of 0 and the correct position is 900000, Array.prototype.find() preformed 12.61ms vs 2.17ms of the simple for loop search(!). am I missing something?
the test code is:
const {performance} = require('perf_hooks');
const _ = require('lodash')
const SIZE = 1000000
const START_I = 0
const ItemVal = 900000
let arr = Array(SIZE).fill(0)
arr = arr.map((a, i) => i)
const myFind = (arr, func, startI) => {
for (let i = startI; i < arr.length; i++) {
if (func(arr[i])) return arr[i]
}
return -1
}
const functions = {
find: () => arr.find(a => a === ItemVal), // looking at all array - no starting index
findSlice: () => arr.slice(START_I).find(a => a === ItemVal),
findLodash: () => _.find(arr, a => a === ItemVal, START_I),
myFind: () => myFind(arr, a => a === ItemVal, START_I),
}
const repeat = 100
const test_find = () => {
for (let [name, func] of Object.entries(functions)) {
let totalTime = 0
for (let i = 0; i < repeat; i++) {
let t_current = performance.now()
func()
totalTime += performance.now() - t_current
}
console.log(`${name}: average time: ${Math.round(totalTime / repeat * 100) / 100}ms`)
}
}
test_find()
what is the best way to find an item in an array stating looking from an index? and also, how does Array.prototype.find perform worse than my own simple for loop implementation of find?
Array#map, Array#filter create a new array and hence effectively iterating over the array (or creating new array).
Whereas in rust, python, java, c#, etc. such expression chain will iterate only once.
In most cases this is irrelevant and we do not have to care about that. However in some cases the performance hit could be a deal breaker to leverage the function api of the Array class.
How do you mitigate this? So you have any preference on a library enabling lazy evaluation for functional expression?
If you don't want it to iterate more than once. You can use a loop
const numbers = [1,2,3,4,5,6]
let result = 0;
for(const number of numbers) {
const square = number * number
if(square % 2) {
result += square
}
}
console.log(result)
Or reduce
const numbers = [1,2,3,4,5,6]
const result = numbers.reduce((acc, number) => {
const square = number * number
if(square % 2) {
return acc + square
}
return acc
}, 0)
console.log(result)
Array methods aren't functional so the whole premise is flawed. The fact that they exist on the array object means they aren't open composition the way pure functions are. You can get closer though
const square = (n) => n * n
const oddNumberOrZero = (n) => n % 2 ? n : 0
const add = (a, b) => a + b
const addOddSquare = (a, b) => add(a, oddNumberOrZero(square(b)))
const reduce = (arr, fn, acc) => arr.reduce(fn,acc)
const numbers = [1,2,3,4,5,6]
const result = reduce(numbers, addOddSquare, 0)
console.log(result)
You also seem to be conflating fluent interfaces with functional programming.
I believe what you are looking for is processing the array as a stream. You can do that with highland:
import _ from "highland";
_([1, 2, 3, 4])
.filter(v => v % 2 === 0)
.map(v => v * 2)
.toArray((result: number[]) => {
// result is the new array
});
Relevant part from the docs:
Arrays - Streams created from Arrays will emit each value of the Array (...)
Please check the following code lines.
In the code, in which v * v is divided 2 means that v is divided.
const numbers = [1,2,3,4,5,6];
const res = numbers.reduce((sum, v)=> sum + (v % 2? v * v: 0), 0);
console.log(res)
Please, how do you populate an array say ‘num’ with numbers not in a second array say ‘fig’? I’m trying to use a loop to have the values of the already populated array ‘fig’ compared to ‘num’ which is to be populated with integers not found in ‘fig’. I’m a bit confused.
If you need to do an array with n numbers you can use this two ways.
const arrayLength = 100;
const numberArray = [...new Array(arrayLength).keys()]
const anotherWay = new Array(arrayLength).fill().map((_, idx) => idx + 1);
console.log(numberArray, anotherWay)
so to do this we have to do a few things:
1) define an existing array with numbers to avoid
2) define length on new array
3) generate a random number and make it an integer
4) check to see if we need to avoid
5) if it's a new value add it to the second array
var first=[55,45,35,1,2,3,4,5];
var second = [];
var i = 7;
var x;
while (i != 0){
x = ~~(Math.random()*100);
var check = false;
for(let j=0; j<first.length;j++){
if(x == first[j]){
check = true;
}
}
if(!check){
second.push(x);
i--;
}
}
console.log(second);
const fig = [-21, 0, 3, 6, 7, 42]
const min = Math.min(...fig) // or fig[0] if the the array is already sorted
const max = Math.max(...fig) // or fig[fig.length - 1]
const num = Array.from({ length: max - min }, (_, i) => i + min)
.filter(el => !fig.includes(el))
or, saving one loop
const num = Array.from({ length: max - min }).reduce((acc, _, i) => {
const curr = i + min
if (!fig.includes(curr)) {
return acc.concat(curr)
}
return acc
}, [])
This is assuming your range is from the smallest number in fig to the largest in fig.
Consider i'm having dynamic array where my items keeps on increment each second.
So i want to remove the last 30 items in the array when array reaches to 60 and keeps the rest in. That is i want to maintain only 30 items in array and remove the older items.
array=[1,2,3,4...........60] //Remove last 30 and show new 30 items
array=[21,22,23...30]
Please suggest me how to achieve this. My Code
If what you want is to drop elements after the 30th
array.length=30;
If you want to drop all but the last 30
array.splice(0, array.length - 30);
here's a demo of both (using 10 instead of 30 for readability of output)
const array = Array.from({length:60}, (_, i) => i);
array.length = 10;
console.log(JSON.stringify(array));
const array2 = Array.from({length:60}, (_, i) => i);
array2.splice(0, array2.length - 10);
console.log(JSON.stringify(array2));
var arr = [1,2,3,4....,60];
function arr_modify(arr,removeLength){
if(arr.length == 60){
arr.splice(0,removeLength)
}
return arr;
}
var modified_array = arr_modify(arr,30);
console.log(modified_array);
console.log(arr);
If you want to keep last N of items use this code:
let numberOfItemsToRemain = 5;
let array = [1,2,3,4,5,6,7,8,9,10];
let size = array.length;
array = array.splice(size-numberOfItemsToRemain, size);
console.log(array);
If you want to keep first N of items, use this code:
let numberOfItemsToRemain = 5;
let array = [1,2,3,4,5,6,7,8,9,10];
array = array.splice(0, numberOfItemsToRemain);
console.log(array);
*Edit numberOfItemsToRemain to 30 in your case.