Reputation: 717
I get an Array with an unknown Number of data. But I only have an predefined amount of data to be shown/store. How can I take every nth Element of the initial Array and reduce it in JavaScript?
Eg.: I get an Array with size=10000, but are only able to show n=2k Elements.
I tried it like that: delta= Math.round(10*n/size)/10 = 0.2 -> take every 5th Element of the initial Array.
for (i = 0; i < oldArr.length; i++) {
arr[i] = oldArr[i].filter(function (value, index, ar) {
if (index % delta != 0) return false;
return true;
});
}
With 0.2 it´s always 0, but with some other deltas (0.3) it is working. Same for delta=0.4, i works, but every second Element is taken with that. What can I do to get this to work?
Upvotes: 43
Views: 126579
Reputation: 1
To separate array every 5 element need to make another 2d array to store every 5 element separately it's my solution if can help to your problem
const arrayParts = [];
var separateEach = 5;
var startLen = 0;
var partCount = Math.ceil(infos.length / separateEach);
console.log('partCount', partCount);
for (var i = 1; i <= partCount; i++) {
arrayParts.push(infos.slice(startLen, separateEach * i));
startLen = separateEach * i;
}
console.log('Parts ', arrayParts);
Upvotes: 0
Reputation: 19
may help!
const myFunction = (a, n) => {
let array = []
for(i = n; i <= a.length; i += n){
array.push(a[i-1]);
}
return array;
}
Upvotes: 0
Reputation: 6553
this also works by using map to create the new array without iterating over all elements in the old array..
// create array with 10k entries
const oldArr = [ ...Array( 10000 ) ].map( ( _el, i ) => i );
const max = 10;
const delta = Math.floor( oldArr.length / max );
const newArr = [ ...Array( max ) ].map( ( _el, i ) => (
oldArr[ i * delta ]
) );
console.log( newArr );
Upvotes: 1
Reputation: 7158
Borrowing from @anonomyous0day's solution, generate a new Array
with the desired indices from the given array:
(Take every 3
items)
Array.prototype.take = function(n) {
if (!Number(n) && n !== 0) {
throw new TypeError(`Array.take requires passing in a number. Passed in ${typeof n}`);
} else if (n <= 0) {
throw new RangeError(`Array.take requires a number greater than 0. Passed in ${n}`);
}
const selectedIndicesLength = Math.floor(this.length / n);
return [...Array(selectedIndicesLength)].map((item, index) => this[index * n + 1]);
};
[1, 2, 3, 4, 5, 6, 7, 8].take(2); // => 2, 4, 6, 8
Upvotes: 0
Reputation: 11008
Try
arr = oldArr.filter(function (value, index, ar) {
return (index % ratio == 0);
} );
where ratio
is 2 if you want arr
to be 1/2 of oldArr
, 3 if you want it to be 1/3 of oldArr
and so on.
ratio = Math.ceil(oldArr.length / size); // size in the new `arr` size
You were calling filter()
on each element of oldAdd
inside a loop and you're supposed to call filter()
on the whole array to get a new filtered array back.
Upvotes: 12
Reputation: 3042
Maybe one solution :
avoid filter because you don't want to loop over 10 000 elements ! just access them directly with a for loop !
var log = function(val){document.body.innerHTML+='<div></pre>'+val+'</pre></div>'}
var oldArr = [0,1,2,3,4,5,6,7,8,9,10]
var arr = [];
var maxVal = 5;
var delta = Math.floor( oldArr.length / maxVal );
// avoid filter because you don't want
// to loop over 10000 elements !
// just access them directly with a for loop !
// |
// V
for (i = 0; i < oldArr.length; i=i+delta) {
arr.push(oldArr[i]);
}
log('delta : ' + delta + ' length = ' + oldArr.length) ;
log(arr);
Upvotes: 63
Reputation: 14593
Filter itself returns an array. If I'm understanding you correctly, you don't need that surrounding loop. So:
newArr = oldArr.filter(function(value, index, Arr) {
return index % 3 == 0;
});
will set newArr to every third value in oldArr.
Upvotes: 33