获取数组javascript的子数组

时间:2013-07-12 20:45:32

标签: javascript arrays

我在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。

4 个答案:

答案 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>

无论你为此或类似的东西编写什么代码,都不要把它内联。发挥作用。