我在javascript中有一个数组,我想要一个数组的子数组,其中元素位于n * 3,n = 0,1,2 ..例如,如果:
var arr = [1,2,3,4,5,6,7,8,9,10,11,12]
var subArr = [1,4,7,10]
编辑:任何没有循环的解决方案。
我在javascript中有一个数组,我想要一个数组的子数组,其中元素位于n * 3,n = 0,1,2 ..例如,如果:
var arr = [1,2,3,4,5,6,7,8,9,10,11,12]
var subArr = [1,4,7,10]
编辑:任何没有循环的解决方案。
这是一个奇特方式的示例:
var brr = [1,2,3,4,5,6,7,8,9,10,11,12].filter(function(_,i){ return !(i%3) })
但是一个简单的循环也一样好(并且与 IE8 兼容)。请注意filter
,即使它不可见,它也会在数组上循环。即使您可以伪装它,您也无法避免循环(至少对于任意大小的数组)。
以下是使用标准循环的方法:
var brr = [];
for (var i=0; i<arr.length; i+=3) brr.push(arr[i])
在此类操作客户端上,性能很少是一个问题,但您可能会发现知道for
循环在这里要快得多:http: //jsperf.com/looporfilter
为了对一组大小为 n、m 次的数据进行操作,其中 m > 1,您将如何避免迭代?真的,除非你使用这样的一组 O(1) 操作,否则没有办法:
var arr = [1,2,3,4,5,6,7,8,9,10,11,12];
var subarr = [];
subarr.push(arr[0]);
subarr.push(arr[3]);
subarr.push(arr[6]);
subarr.push(arr[9]);
这是一个结构递归(可以用循环表示,并且在技术上是循环)。
var arr = [1,2,3,4,5,6,7,8,9,10,11,12];
var subarr = [];
(function recur(n){
if( n >= arr.length ) return;
subarr.push(arr[n]);
recur(n+3);
})(0);
注意:直接的 for 循环总是更快。在 @dystroy 的 jsperf 的扩展中,此递归的运行速度比 for 循环慢,但比过滤器快。http://jsperf.com/looporfilter/2
只是为了好玩,我寻找一种方法来实际做到这一点,而无需像 OP 想要的那样循环。不使用循环,这很难。我能管理的最接近的得到正确的数字,但将它们转换为字符串而不是数字。
var r=[1,2,3,4,5,6,7,8,9,10,11,12,13,14];
alert( "".replace.call(r+",-0,-0,-0", /(\d+),\d+,?(\d+,|$)/g, "$1,")
.replace(/(,?\-0){1,4}$/g,"")
.split(",") );
//shows: 1,4,7,10,13
如果您需要强数字,这很容易,但我不确定在 .split(",") 之后添加 .map(Number) 是否会在您的书中构成一个循环,但这是唯一真正找到所需结果的版本一个循环。
这也仅适用于编码的正整数。
再次,比我推荐使用的东西更有趣;不要害怕循环...
这是一个没有循环的解决方案:
var arr = [1,2,3,4,5,6,7,8,9,10,11,12];
// pickInterval is a function that automatically picks every "n"
// elements from an array, starting with the first element
var subArr = pickInterval( arr, 3 );
// now subArr is [1,4,7,10]
很简单,不是吗?而且看不到一个循环。
啊,但是你问,“有什么问题?你还没有实现那个pickInterval()
功能,是吗?我敢打赌它里面有一个循环。”
你是对的。即使我们pickInterval()
使用其他看起来不像循环的函数来编写我们的函数,该函数也会有一个循环。如果那个只是调用另一个函数,最终你会发现一个循环。
它可能一直是海龟,但它们下面都有一个循环。
因此,要实现pickInterval()
,我们可以使用@dystroy 回答中的任何一种方法。我们可以将循环放在函数内部:
function pickInterval( array, interval ) {
var result = [];
for( var i = 0, n = array.length; i < n; i += 3 )
result.push( array[i] );
return result;
}
或者我们可以使用.filter()
:
function pickInterval( array, interval ) {
return array.filter( function( _, i ){
return !( i % 3 );
});
}
当然这里还有一个循环,在里面.filter()
。它只是对我们隐藏起来,就像对pickInterval()
调用者隐藏任何循环一样。
这才是真正的重点。使用.filter()
,使用for
循环,使用任何你想要的,只要你将它封装在一个函数中。那么该函数的内部工作原理就无关紧要了。如果您喜欢for
循环,因为它快速且易于理解,请使用它。如果您喜欢这个filter()
版本,因为它有趣且优雅,请使用它。如果您以后需要在一个非常大的数组上使用它并且它运行缓慢,您可以将其替换为for
循环版本,而不会影响使用 pickInterval()
.
无论您为此或类似的东西编写什么代码,都不要将它内联。做一个函数。