将数组理解转换为`map`和`filter`

时间:2016-02-11 11:08:37

标签: javascript arrays list-comprehension

数组理解是Firefox(Gecko)的一个非标准功能,Mozilla文档本身建议使用mapfilter

您能否将以下数组理解转换为mapfilter的组合?

var numbers = [ 1, 2, 3, 4, 5 ];
var letters = [ "a", "b", "c", "d", "e" ];

var cross = [for (i of numbers) 
             for (j of letters) 
             if (i % 2 == 0) i+j];

预期结果:

[ '2a', '2b', '2c', '2d', '2e', '4a', '4b', '4c', '4d', '4e' ]

2 个答案:

答案 0 :(得分:1)

您需要做的是首先获取笛卡尔积,然后您可以过滤并映射生成的数组。

的Python

from itertools import product

numbers = [ 1, 2, 3, 4, 5 ]
letters = [ 'a', 'b', 'c', 'd', 'e' ]

cross = map(lambda x:'{0}{1}'.format(*x),filter(lambda e:e[0]%2==0,product(numbers,letters)))

print cross # ['2a', '2b', '2c', '2d', '2e', '4a', '4b', '4c', '4d', '4e']

的JavaScript



// Source: http://stackoverflow.com/a/15310051/1762224
function cartesian() {
  var r = [], args = arguments, max = args.length - 1;
  function helper(arr, i) {
    for (var j = 0, l = args[i].length; j < l; j++) {
      var a = arr.slice(0).concat(args[i][j]); // Clone arr
      if (i === max) { r.push(a); }
      else { helper(a, i + 1); }
    }
  }
  helper([], 0);
  return r;
}

var numbers = [ 1, 2, 3, 4, 5 ];
var letters = [ 'a', 'b', 'c', 'd', 'e' ];

var cross = cartesian(numbers, letters)
          . filter(function(item, index, arr) { return item[0] % 2 === 0; })
          . map(function(item, index, arr)    { return item.join(''); });

console.log(cross); // [ '2a', '2b', '2c', '2d', '2e', '4a', '4b', '4c', '4d', '4e' ]
&#13;
&#13;
&#13;

更高效的设计

正如Andy在评论中建议的那样,您可以提前过滤numbers数组,这样您就不需要创建如此大的产品。

var cross = cartesian(
        numbers.filter(function(number) {
            return number % 2 === 0;
        }),
        letters)
    .map(function(item) {
        return item.join('');
    });

答案 1 :(得分:0)

此答案还使用reduce来平展输出:

function comp(numbers, letter) {

  // filter out the even numbers
  return numbers.filter(function (number) {
    return number % 2 === 0;
  }).map(function (number) {

    // for each letter append the number that we're currently
    // iterating (from map)
    return letters.map(function (letter) {
      return number + letter;
    });

  // use reduce and concat to flatten the output of two nested
  // arrays into one array
  }).reduce(function (p, c) {
    return p.concat(c);
  });
}

comp(numbers, letters); // [ "2a", "2b", "2c", "2d", "2e", "4a", "4b", "4c", "4d", "4e" ]

DEMO