Reputation: 43
Having the following input:
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'}]
}]
Using map
and filter
I want to achieve:
var desired = [
'foo POST /foo1',
'foo GET /foo2',
'bar PUT /:id',
]
Complete 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',
//]
This is the structure which is is used in my code and I want to achieve my desired output with the small change and still using map
and filter
.
Upvotes: 4
Views: 470
Reputation: 5963
After filtering your input, you can map
each set of routes into the desired format, then use concat
to join these arrays together:
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 references:
const,
arrow functions with destructuring parameters,
template literals, and
spread operator.
Upvotes: 0
Reputation: 16710
You need to iterate through your routes
array as well within every item and map the values to get the verb
and 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);
Upvotes: 0
Reputation: 4050
You can use a loop inside of the map function to ensure you look at all routes for a given name. That will return an array of arrays, so I used reduce after the map to flatten that into a single array of strings.
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);
});
This results in myOutput of ["foo POST /foo1", "foo GET /foo2", "bar PUT /:id"]
.
Upvotes: 2