2013-05-18 29 views
0

我试图将值映射到一个新的数组。问题是我映射的属性可以是数字或数组。foreach array.map()

对于数组,我有一个问题,因为我的结果是一个关联数组。我的目标是将[[1,2,3], [1,2,3]](见下文)转换为[1,2,3,1,2,3]。换一种说法;只是让它成为一维数组。

我试过用map()里面的foreach循环,但没有成功。有任何想法吗?

var list = [{ foo: 1, bar: [1,2,3] }, { foo: 2, bar: [1,2,3] }]; 

var retArr = list.map(function (v) { 

    return v.bar; 

}); 

console.log(retArr); // [[1,2,3], [1,2,3]] 

var list = [{ foo: 1, bar: [1,2,3] }, { foo: 2, bar: [1,2,3] }]; 

var retArr = list.map(function (v) { 

    if($.isArray(v.bar)){ 

     $.each(v.bar, function(i, v){ 

      return v; 
     }); 

    } else { 

     return v.bar; 
    } 
}); 

console.log(retArr); // [undefined, undefined] 

http://jsfiddle.net/Mck7N/

回答

4

如果使用jQuery's map function,你会得到阵列自动展平:

该函数可以返回[...]值的数组,将被夷为平地。

var retArr = $.map(list, function (v) { 
    return v.bar; 
}); 

在你的第二个例子,你[undefined, undefined]的结果,因为你没有返回从回调的值。 $.each回调的返回值不影响.map回调的返回值。

.map在这里没有帮助你,因为你只能从回调中返回一个值。相反,您可以遍历数组:

var retArr = []; 

list.forEach(function (v) { 
    if ($.isArray(v.bar)) { 
     retArray.push.apply(retArray, v.bar); 
    } 
    else { 
     retArray.push(v.bar); 
    } 
}); 

或者,您可以使用Array#reduce。但是,既然你使用jQuery,使用它的map函数是最简单的解决方案。

+0

+1,这是相当整洁。 – Blender

+0

我不知道它被称为“平坦”。如果我这样做了,我可能会发现它:-)谢谢 – Johan

2

没有JQuery的,你也可以使用扁平Array.reduce

var list = [{ foo: 1, bar: [1,2,3] }, { foo: 2, bar: [1,2,3] }] 
    ,retArr = list.reduce(function (a,b) { 
       return a.concat(b.bar); 
       },[] 
      ); 
//=> retArr = [1,2,3,1,2,3] 
+0

在你的第一个例子中,map的返回值从来没有被使用,所以你应该用forEach替换map,它会做同样的事情,但什么都不返回。你也可以删除“返回v;”。在第二个示例中,将全局变量retArr设置为[],然后调用map。如有可能,应尽量避免全局变量。 – SpiderPig

+0

@SpiderPig:你有部分权利。改变了使用'Array.reduce'的答案,这给了OP一个班轮。 – KooiInc

0

不能使用map孤单,因为这只会返回数组或数字数组。然而,您可以拼合说成一个阵列使用concat

var retArr = [].concat.apply([], list.map(function(v) { return v.bar; })); 

如果使用Underscore,你甚至可以缩短到这

var retArr = _.flatten(_.pluck(list, "bar"), true);