2016-05-25 10 views
3

die folgende Eingabe Mit:`map` und` filter` in JavaScript

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'}] 
    }] 

Mit map und filter Ich möchte erreichen:

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

komplette Code:

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', 
    //] 

Dies ist die Struktur, die in meinem Code verwendet wird und ich möchte meine gewünschte Ausgabe mit dem kleinen erzielen ändern und immer noch mit map und filter.

+0

ja gibt es eine Möglichkeit, in mein Array zu loopen? –

+0

Ich verstehe nicht, Sie erwarten "foo GET/foo2" in Ihrer Ausgabe? Aber Sie haben es explizit herausgefiltert. –

+0

Ja, wie kann ich innerhalb meiner 'map'-Funktion in mein Routenverzeichnis aufnehmen? –

Antwort

2

Sie können eine Schleife innerhalb der Kartenfunktion verwenden, um sicherzustellen, dass Sie alle Routen nach einem bestimmten Namen durchsuchen. Das wird ein Array von Arrays zurückgeben, also habe ich reduce nach der Map verwendet, um das in ein einzelnes Array von Strings zu reduzieren.

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); 
     }); 

Dies führt zu myOutput von ["foo POST /foo1", "foo GET /foo2", "bar PUT /:id"].

0

Sie müssen in jedem Element als auch durch Ihre routes Array zu durchlaufen und die Werte der Karte die verb und path

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);

0

Nach dem Filtern Sie Ihre Eingabe zu erhalten, können Sie map jeder Satz von Routen in das gewünschte Format, verwenden Sie dann concat, um diese Arrays miteinander zu verbinden:

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)));

ES6 Version

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)));

ES6 Referenzen:
const,
arrow functions mit destructuring Parametern,
template literals und
spread operator.