在对象中的多个数组上使用map和filter

时间:2015-07-09 20:51:18

标签: javascript dictionary functional-programming

使用维基百科的API,我得到了一个看起来像这样的对象:

-ffunction-sections -fdata-sections

第一个数组包含 titles ,第二个是描述,第三个是 links

部分说明可能为空(“”)。

示例 -

Example

我想将所有三个数组合并为一个数组,如下所示:

obj = {["string", Array[10], Array[10], Array[10]]}

但如果描述不为空,则仅合并 - [{title: obj[1][0], desc: obj[2][0], link: obj[3][0]}, ... , {title: array[1][9], desc: obj[2][0], link: obj[3][0]}]

我设法使用for循环和if:

obj[2][i] !== ""

有没有办法使用javascript的高阶函数以更优雅的方式实现相同的目标?例如var arr = []; for (var i = 0; i < data[1].length; i++) { if (data[2][i] !== '') { arr.push({title: data[1][i], desc:data[2][i], link: data[3][i]}); } } map(也许filter?)

由于

修改

我最终做到的方式是:

reduce

3 个答案:

答案 0 :(得分:2)

如果你不想要的话,没有必要涉及另一个图书馆。在这里映射和过滤工作,但我认为它们增加了很多长度。我赞成每个人。

请注意,Array.prototype.forEach会将最多三个参数传递给您的回调函数。在这种情况下,您可以使用两个。

data[2].forEach(function(elem, index) {
  elem && arr.push({title: data[1][index], desc: elem, link: data[3][index]});
}); 

使用地图和过滤器的解决方案可能看起来像

data[1].map(function(elem, index) {
  return ({
    title: data[1][index],
    description: data[2][index],
    link: data[3][index]
  });
}).filter(function(elem) {
  return elem.description;
});

答案 1 :(得分:2)

您即将学习一个非常棒的新高阶函数, zip !说实话,我很少遇到有用的情况,但你的例子恰好适合它。

/*
 Example in ES6. In order to run, first install node and then go
  npm install -g babel
  npm install underscore
  babel thisfile.js | node
*/

let _ = require('underscore')

let resp = [
  "Football",
  ['Football', 'Soccer'],
  ['FootballDescription', 'SoccerDescription'],
  ['http://football.com', 'http://soccer.com']
]

// 1. Throw away the first string, e.g. "Football"
resp.shift()

// 2. Use zip to make an array of intersected arrays, i.e
// [
//   ['Football', 'FootballDescription', 'http://football.com'],
//   ['Soccer', 'SoccerDescription', 'http://soccer.com']
// ]
// and then use map to make each array into a nicely named object
let objects = _.zip(
  resp[0],
  resp[1],
  resp[2]
).map(x => ({
  name: x[0],
  desc: x[1],
  link: x[2]
}))

console.log(objects)
/*
Output:
[ { name: 'Football',
    description: 'FootballDescription',
    link: 'http://football.com' },
  { name: 'Soccer',
    description: 'SoccerDescription',
    link: 'http://soccer.com' } ]
*/

答案 2 :(得分:1)

看起来你生活中需要一些lodash /下划线......

http://underscorejs.org/ https://lodash.com/

他们是完全相同的库。取对象/阵列并切片并切块,直到它们符合您的要求。超级有用。

或者你可以在普通的'减少...

中做到这一点
var crazyArray = ['title here', ['one', 'two', 'three'], ['four', 'five'], '', ['six']]
var reduced = crazyArray.reduce(function( last, cur ){
  if(cur) return last.concat(cur);
  return last;
}, []);
console.log(reduced) // [ 'title here', 'one', 'two', 'three', 'four', 'five', 'six' ]