2013-05-18 35 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);