JavaScript:获取数组中每第n个元素

40

我得到了一个不知道有多少数据的数组。 但是我只有一个预定义的数据量要显示/存储。 在JavaScript中如何取出初始数组中每个第n个元素并将其缩小?

例如:我得到一个大小为10000的数组,但只能显示n=2k个元素。

我尝试了这样做: delta = Math.round(10 * n / size) / 10 = 0.2 -> 取出初始数组中每5个元素中的一个。

for (i = 0; i < oldArr.length; i++) {
  arr[i] = oldArr[i].filter(function (value, index, ar) {
    if (index % delta != 0) return false;
    return true;
  });
}

当delta=0.2时,结果总是为0,但是对于其他一些delta(如0.3),它可以正常工作。当delta=0.4时,也可以工作,但是每隔一个元素会被取走。我该如何解决这个问题?


什么是 n?什么是 k?什么是 delta?什么是 oldArr - Oriol
delta = size / n怎么样? - Felix Kling
0.2可以均匀地整除所有整数,因此someInt%0.2 == 0始终成立。我认为你想要someInt%(1/0.2),即someInt%5 - James
1
@James 在我的电脑上,1%0.2的结果是0.19999999999999996,因为浮点数运算存在问题 - Oriol
@Oriol 没错! 1%0.25 可以工作(因为我猜测0.25可以在二进制中被准确表示),使用JS上的非整数操作符可能是个坏主意。 - James
Oriol,我在我的起始帖子中写了这些变量是什么。@FelixKling,哈哈,那听起来很合理。 - EsoMoa
6个回答

63
也许有一个解决方案:
避免使用过滤器,因为您不想循环处理10000个元素!只需使用for循环直接访问它们即可!

 
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);


1
谢谢,我想就这样吧。特别是因为这应该比取模检查更快。而且我没有10k个元素。这是一个二维数组,所以在另一个版本中甚至会有100k个检查。 - EsoMoa

32

过滤器本身会返回一个数组。如果我理解你的意思正确,那么你不需要那个外围循环。所以:

Filter本身返回一个数组。如果我理解你的意思正确,你不需要那个包含它的循环。所以:

newArr = oldArr.filter(function(value, index, Arr) {
    return index % 3 == 0;
});

将oldArr中每三个值设为newArr的值。


12

尝试

arr = oldArr.filter(function (value, index, ar) {
    return (index % ratio == 0);
} );

其中,如果您希望 arroldArr 的1/2,则 ratio 为2;如果您希望它是 oldArr 的1/3,则为3,依此类推。

ratio = Math.ceil(oldArr.length / size); // size in the new `arr` size

你在循环中对oldAdd的每个元素调用了filter(),实际上应该对整个数组调用filter()以获得一个新的过滤后的数组。


难道不应该使用 Math.ceil() 来防止新数组的大小超过所需大小吗? - StoicJester

0

可能有所帮助!

 const myFunction = (a, n) => {

   let array = []


    for(i = n; i <= a.length; i += n){
      array.push(a[i-1]);

   }

  return array;

}

0

这也可以通过使用map来创建新数组而无需迭代旧数组中的所有元素来实现。

// 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 );


0
@anonomyous0day的解决方案中借鉴,使用给定数组生成一个新的Array,该数组包含所需的索引:
(每隔3个项取一次)
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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接