I make _.reduce on all elements of my array,unfortunately sometimes the array is just too big.
I want to make reduce on only constant number of elements from the array.
What do you suggest me to do?
You can use Array.prototype.slice to make a (temporary) copy of the first n elements of the array:
_.reduce(myArray.slice(0, n), ...);
If there are less than n elements in the array it'll just use all of them.
How about using _.first to get the the number of items you want to reduce:
// reduce the first 100 items in the array
var result = _.reduce( _.first(data, 100), fn, memo)
Related
splice is time complexity O(n);
I tried this version instead of splice:
which has added space complexity but i think less time complexity.
let arr = [0,1];
arr[5] = 5;
// i need to push numbers into this index only-not to the whole array
// push wont work on a 1d array but will work on 2d array
arr[5] = [[], 5];
// now it is possible to push into this index
arr[5].push(15,125,1035);
// remove the unnecessary empty cell []
arr[5].shift();
console.log(arr) // result [0,1,[5,15,125,1035]]
So is this worse than splice, or better(in terms of time complexity)?
EDIT:
this is a bad take of the answer given, my problem was i didn't understand why you couldn't push into an index of an array.
when you try:
arr = [1,2,3,4]
and then arr[1].push(2.5);
you would get an error since you try and push into a primitive(number and not an object/array).
My mistake was that i thought JS just doesn't allow it.
If you want result [5,15,125,1035] with simply this way.
let arr = [5];
arr.push(15,125,1035);
console.log(arr)
Javascript leaves the underlying implementation of arrays up to the runtime, so the answer will depend on implementation used: How are JavaScript arrays implemented?
but I will assume this array is entirely a flat array.
Pushing to the end of an flat array is only O(1) if the array has space for more elements. Otherwise the array needs to be reallocated which is O(length_of_array). However it should still be faster than splicing on every insertion.
If you want O(1) insertion speed then you could append to the end of a doubly linked list instead, however this is at the cost of space and lookup/iteration speed.
the simpler answer i was looking for is by #Gerardo Furtado
let arr = [0,1,2,3,4,5];
arr[5] = [5];
arr[5].push(15,125,1035);
console.log(arr) // result [0,1,[5,15,125,1035]]
To be able to use setValues() instead of setValue on a high number of rows, I would like to know how can I convert all my arrays into arrays of the same length.
During a map function, I create one giant array that looks like this :
const myArray = [[Monday, Tuesday],[Monday,Tuesday,Wednesday],[Friday],[Monday,Friday],[Tuesday,Wednesday,Friday]] // And so on.
At the moment I use a setValue for each item of the array. The next step would be simply to use setValues(), and append an array but the problem is they are all of different lengths.
result.forEach(function(_,index){
currentSheet.getRange(1+index,5).setValue(result[index]);
});
That is going to do that for 600 lines and I will do it several times with other functions. I can live with it, but it seems like a waste. Is there a way to make the arrays homogenous (all arrays would be have a length of 3 elements, one or two being empty for example) an use one single setValues() instead ?
EDIT : the original map function to create the first array was requested. Here it is :
(Basically what it does is : it runs a map through a first array, look at the first element and go find in the source all the elements that have the same key and return the 9th and 10th elements of that array)
const result = UniquesDatas.map(uniqueRow =>
SourceDatas
.filter(row => row[0] === uniqueRow[0])
.map(row => [row[9]+" "+row[10]])
);
Thank you in advance,
Cedric
You can concat an array of empty elements of the remaining length.
const myArray = [['Monday', 'Tuesday'],['Monday','Tuesday','Wednesday'],['Friday'],['Monday','Friday'],['Tuesday','Wednesday','Friday']]
const res = myArray.map(x => x.concat(Array(3 - x.length)));
console.log(res);
As suggested by Kinglish, to get the length of the inner array with the most elements, use Math.max(...myArray.map(x=>x.length)), which will work for the more general case.
I have been doing research on the benefits of using reduce over map. Mainly the benefit is that reduce has better performance time.
My question is how would i be able to use reduce to iterate over an array as if i would for the map function ?
An example
The following code combines the fruits to one string. How would i be able to iterate over this array using the reduce function ?
const fruits = ['pears', 'plums', 'grapes', 'apples']
console.log(fruits.reduce( (acc, fruit) => acc.concat(fruit)))
// "pearsplumsgrapesapples"
You'll sacrifice code legibility for a millisecond of difference but here it is:
['pears', 'plums', 'grapes', 'apples'].reduce(function (acc, currentFruit) {
// Your code here
acc.push(currentFruit);
return acc;
}, []);
You'll have to push your current value to a an array because the reduce method objective is to reduce the provided data to a single value.
At the end of the day, map is just better, simpler and you won't be able to notice the time difference.
The reduce function indeed iterates over the array, because it's meant to reduce all the array items to a single value by applying a function.
The map function iterates on the array too, in order to project the array elements to a value calculated by applying a provided function.
The difference between the two functions is that they are iterating over the array for a different purpose. Reduce is used to compute single value, map is used to project each array item to a new value.
In both cases you can't say anything about the computational complexity because you are passing a callback and you don't know what that callback is going to do. So the computational complexity depends on the callback function.
Take a look at this paper about reduce: https://hackernoon.com/javascript-array-reduce-50403c421968
You could pass an empty array as the reduce function accumulators initial value, then within the body of your reduce function you can append to the acc which will now be an array and execute conditional logic.
map is simple. It calls the function on each element of the input array, and returns a new array containing the corresponding function results.
result = array.map(f)
is equivalent to
result = [f(array[0], 0, array), f(array[1], 1, array), f(array[2], 2, array), ...]
You use reduce if you want to combine the results of each iteration in a custom way, to produce one result. The function takes two arguments -- the first is the return value of the previous iteration, and the second is the current element from the iteration.
result = array.reduce(f, init)
is equivalent to
temp1 = f(init, array[0], 0, array);
temp2 = f(temp1, array[1], 1, array);
temp3 = f(temp2, array[2], 2, array);
...
result = f(tempN, array[N], N, array);
If you don't provide an initial value argument, the first line becomes
temp1 = array[0];
and the rest is the same.
If you don't actually need a new result, you just want to execute some code on each array element, you use forEach(). It's like map, but it doesn't collect the results. If you want to log each array element on a new line, you would do:
array.forEach(el => console.log(el));
this.arol.filter(x=>x.length!==0
?(this.arol.splice(this.arol.indexOf(x),1))
:!true)
I was trying to change it many different ways, but it still does not delete all elements of the array, it always leaves 1 or 2 behind deleting most of them.... I think the problem is with the condition... We are checking if the length of array elements is not 0 (which are all strings)...
Don't try to splice while filtering - instead, return from the filter callback a truthy or falsey value, depending on whether you want to include the item being iterated over in the new array, and use the resulting array that gets returned from .filter:
this.arol = this.arol.filter(x => x.length !== 0);
^^^^^^^^^^^^
If you want to maintain same outer array reference and mutate original you can splice in a loop if you work from end to start so as not to affect indexing you haven't arrived at yet as you change the array length:
const arr = [[1],[],[2]]
arr.reduceRight((_,c,i) => c.length || !!arr.splice(i,1))
console.log(arr)
The problem is you are trying to splice at the same time you are using filter. Filter does not remove elements from your array, it creates a new array with the filtered data, as described here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
You can assign the result to the same array as suggested by CertainPerformance.
If Splice is removed from that code then it will not delete elements. this.arol.splice(this.arol.indexOf(x),1) here it will iterate through every element inside that array and x will be current iteration which will splice from the array as you have written splice method. Remove splice it will work fine.
I am trying to use the following prototype to fill an empty array with integers from 1-100. As per MDN's documentation:
array.prototype.fill(value, [optional start & end index])
If my understanding is correct if I call my value = 1 then if I say:
[5].fill(1); I would be left with an array with 1 sitting at all 5 index points of the array. Is there a way using .fill() to say value = 1...100? I'm beginning to think running a for loop to push values 1 - 100 might be the only way to do this, but I thought I would see if this method worked the same.
No, fill method, doesn't take a function or an iterator as an argument to change the static value with every iteration.
try this approach
var N = 100;
var arr = Array.apply(null, {length: N+1}).map(Number.call, Number);
arr.splice(0,1);
console.log(arr);
splice at the end removes the first item of the array which was 0.
If you don't want to do splice
var N = 100;
var arr = Array.apply(null, {length: N}).map(Number.call, function(item, index){ return item + 1 });
console.log(arr);
Some other good approaches are mentioned in this answer to fill values dynamically.
The fill() method fills all the elements of an array from a start index to an end index with a static value.
Therefore, it will not be possible to increment this value using the fill() method.