javascript中的`map`和`filter`

时间:2016-05-25 20:02:53

标签: javascript node.js

有以下输入:

var m = [{
    name: 'foo',
    routes: [{verb: 'post', path: '/foo1'},
      {verb: 'get', path: '/foo2'}]
  }, {
    name: 'bar',
    routes: [{verb: 'put', path: '/:id'}]},
  {
    name: '__ignoreme',
    routes: [{verb: 'post', path: '/baz1'},
      {verb: 'get', path: '/baz2'}]
  }]

使用mapfilter我希望实现:

  var desired = [
  'foo POST /foo1',
  'foo GET /foo2',
  'bar PUT /:id',
]

完整代码:

    var m = [{
        name: 'foo',
        routes: [{verb: 'post', path: '/foo1'},
          {verb: 'get', path: '/foo2'}]
      }, {
        name: 'bar',
        routes: [{verb: 'put', path: '/:id'}]},
      {
        name: '__ignoreme',
        routes: [{verb: 'post', path: '/baz1'},
          {verb: 'get', path: '/baz2'}]
      }]



    var desired = [
      'foo POST /foo1',
      'foo GET /foo2',
      'bar PUT /:id',
    ]


    var myOutput = m
            .filter(function (m) {
              return m.name.indexOf('__') === -1;
            })
            .map(function (m) {
              return [
                m.name,
                m.routes[0].verb.toUpperCase(),    // I should loop through my array instead of getting just the first element
// But can I loop through the array in my map?        
                m.routes[0].path
              ].join(' ');
            });


    console.log('>myOutput:', myOutput);
    // What I achieve which is not desired : 
    // [
    // 'foo POST /foo1',
    //  'foo PUT /:id',
    //]

这是我的代码中使用的结构,我希望通过较小的更改实现我想要的输出,并且仍然使用mapfilter

3 个答案:

答案 0 :(得分:2)

您可以在map函数中使用循环,以确保查看给定名称的所有路径。这将返回一个数组数组,所以我在map之后使用reduce将其展平为一个字符串数组。

var myOutput = m
        .filter(function (m) {
          return m.name.indexOf('__') === -1;
        })
        .map(function (m) {
          var arr = [];
          for(var i = 0; i < m.routes.length; i++){
            arr.push([
              m.name,
              m.routes[i].verb.toUpperCase(),            
              m.routes[i].path
            ].join(' '));
          }
          return arr;
        }).reduce(function(prev, cur){
          return prev.concat(cur);
        });

这会导致myOutput为["foo POST /foo1", "foo GET /foo2", "bar PUT /:id"]

答案 1 :(得分:0)

您需要遍历每个项目中的routes数组并映射值以获取verbpath

 var m = [{
        name: 'foo',
        routes: [{verb: 'post', path: '/foo1'},
          {verb: 'get', path: '/foo2'}]
      }, {
        name: 'bar',
        routes: [{verb: 'put', path: '/:id'}]},
      {
        name: '__ignoreme',
        routes: [{verb: 'post', path: '/baz1'},
          {verb: 'get', path: '/baz2'}]
      }]



    var desired = [
      'foo POST /foo1',
      'foo GET /foo2',
      'bar PUT /:id',
    ]


    var myOutput = m
            .filter(function (a) {
              return a.name.indexOf('__') === -1;
            })
            .map(function (a) {
              return a.routes.map(function (item) {
                return [
                  a.name,
                  item.verb.toUpperCase(),  
                  item.path
                ].join(' ');
              });
            })
            .reduce(function(prev, current){
              return prev.concat(current);
            })


    document.write('>myOutput:', myOutput);

答案 2 :(得分:0)

过滤输入后,您可以map将每组路由转换为所需的格式,然后使用concat将这些阵列连接在一起:

&#13;
&#13;
var m = [
    {
        name: 'foo',
        routes: [
            {verb: 'post', path: '/foo1'},
            {verb: 'get', path: '/foo2'}]
    },{
        name: 'bar',
        routes: [
            {verb: 'put', path: '/:id'}]
    },{
        name: '__ignoreme',
        routes: [
            {verb: 'post', path: '/baz1'},
            {verb: 'get', path: '/baz2'}]
    }
];

var filter = function(a){
    return a.filter(function(x){
        return x.name !== '__ignoreme';
    });
};

var format = function(name, route){
    return name + ' ' + route.verb.toUpperCase() + ' ' + route.path;
};

var process = function(a){
    if(!a.length){
        return [];
    }
    return a[0].routes.map(function(r){
        return format(a[0].name, r);
    }).concat(process(a.slice(1)));
}

console.log(process(filter(m)));
&#13;
&#13;
&#13;

ES6版本

&#13;
&#13;
const m = [
    {
        name: 'foo',
        routes: [
            {verb: 'post', path: '/foo1'},
            {verb: 'get', path: '/foo2'}]
    },{
        name: 'bar',
        routes: [
            {verb: 'put', path: '/:id'}]
    },{
        name: '__ignoreme',
        routes: [
            {verb: 'post', path: '/baz1'},
            {verb: 'get', path: '/baz2'}]
    }
];

const filter = xs => xs.filter(x => x.name !== '__ignoreme');
const format = (name, route) => `${name} ${route.verb.toUpperCase()} ${route.path}`;
const process = ([x,...xs]) =>
    x === undefined ? [] : [...x.routes.map(r => format(x.name,r)), ...process(xs)];

console.log(process(filter(m)));
&#13;
&#13;
&#13;

ES6参考:
const
带有arrow functions参数的destructuring
template literals
spread operator