【问题标题】:Javascript: take every nth Element of ArrayJavascript:获取数组的每一个元素
【发布时间】:2022-04-14 04:52:35
【问题描述】:

我得到一个包含未知数量数据的数组。 但我只有预定义的数据量要显示/存储。 如何在 JavaScript 中获取初始数组的每个第 n 个元素并减少它?

例如:我得到一个 size=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;
  });
}

对于 0.2,它始终为 0,但对于其他一些增量 (0.3),它正在工作。 delta = 0.4 相同,我可以工作,但每隔一个元素就会被带走。我该怎么做才能让它发挥作用?

【问题讨论】:

  • 什么是nk 是什么? delta 是什么? oldArr 是什么?
  • delta = size / n 怎么样?
  • 0.2 均分所有整数,所以someInt % 0.2 == 0 总是。我想你想要someInt % (1 / 0.2),即someInt % 5
  • @James 1 % 0.2 为我生成 0.19999999999999996,因为 floating point math is broken
  • @Oriol 你是对的! 1 % 0.25 有效(因为 0.25 可以精确地表示为二进制,我想),我想在非整数操作数上使用模运算符在 JS 中是个坏主意。

标签: javascript arrays


【解决方案1】:

也许一个解决方案:

避免使用过滤器,因为您不想循环超过 10 000 个元素! 只需使用 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);

【讨论】:

  • 谢谢,我想就是这样。特别是因为这应该比模检查更快。而且我没有 10k 元素。它是一个二维数组,所以在另一个版本中甚至会有 100k 次检查。
【解决方案2】:

过滤器本身返回一个数组。如果我对您的理解正确,则您不需要那个周围的循环。所以:

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

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

【讨论】:

    【解决方案3】:

    试试

    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()来防止新数组大于想要的大小吗?
    【解决方案4】:

    @anonomyous0day's solution 借用,使用给定数组中的所需索引生成一个新的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
    

    【讨论】:

      【解决方案5】:

      这也可以通过使用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 );

      【讨论】:

        【解决方案6】:

        可能有帮助!

         const myFunction = (a, n) => {
        
           let array = []
        
        
            for(i = n; i <= a.length; i += n){
              array.push(a[i-1]);
        
           }
        
          return array;
        
        }
        

        【讨论】:

          猜你喜欢
          • 2018-01-24
          • 2023-03-26
          • 1970-01-01
          • 2011-07-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-05
          • 1970-01-01
          相关资源
          最近更新 更多