我在javascript中有一个数组,我想要一个带有元素的数组的子数组,它位于位置n * 3,n = 0,1,2 ..例如if:
var arr = [1,2,3,4,5,6,7,8,9,10,11,12]
var subArr = [1,4,7,10]
编辑:没有循环的任何soln。
答案 0 :(得分:6)
这是一个奇特的例子:
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
答案 1 :(得分:0)
为了对大小为n,m次的数据集进行操作,其中m> 1。 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);
要注意:直接循环将始终更快。在@ dystroy的jsperf的扩展中,这种递归比for循环运行得慢,但比过滤器更快。 http://jsperf.com/looporfilter/2
答案 2 :(得分:0)
只是为了踢,我搜索了一种方法,实际上没有像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(数字)会在您的书中构成一个循环,但这是唯一实际找到的没有循环的期望结果。
这也仅适用于编码的正整数。
再次,比我推荐使用的东西更有乐趣;不要害怕循环...
答案 3 :(得分:0)
这是一个没有循环的解决方案:
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()
。< / p>
无论你为此或类似的东西编写什么代码,都不要把它内联。发挥作用。