在javascript中从JSON对象创建独特月份数组(无for循环)

时间:2018-03-05 00:13:49

标签: javascript data-manipulation

我在javascript中学习d3,正在研究一些基本的数据操作。我有一个年/月/出生数据的简单JSON对象,如下所示:

var birthData = [
  { 
    "year": 1967, 
    "month": "January", 
    "births": 31502 
  },
  { 
    "year": 1967, 
    "month": "January", 
    "births": 26703 
  },
  { 
    "year": 1967, 
    "month": "February", 
    "births": 28853 
  },
  { 
    "year": 1967, 
    "month": "February", 
    "births": 26958 
  },
  { 
    "year": 1967, 
    "month": "February", 
    "births": 28591 
  },
  { 
    "year": 1967, 
    "month": "March", 
    "births": 29545 
  },
  { 
    "year": 1967, 
    "month": "March", 
    "births": 30086 
  }]

我想简单地创建一个出现在这个JSON对象中的独特月份数组,如下所示:

["January", "February", "March"]

我宁愿避免使用这种方法

var months = [];
for(var i = 0; i <= birthData.length; i++) {
  var month = birthData[i].month
  if(months.indexOf(month) === -1) {
    months.push(month)
  }
}

有更有效的方法吗?

编辑:作为一个快速跟进的问题,是否有任何非常好的资源用于学习使用javascript进行数据操作(尤其是使用d3或其他图形库)。在javascript中快速进行数据操作会让我的生活更轻松!

3 个答案:

答案 0 :(得分:2)

使用reduce是一种巧妙的方法:

var months = birthData.reduce((accumulator, item) => 
  accumulator.includes(item.month) 
    ? accumulator 
    : [ ...accumulator, item.month ], []);

这样做是在构建新数组(accumulator)时循环遍历所有项目,并且在检查是否已将一个月添加到此新数组的条件下,确定是否应添加月份当前项目与数组的关系。

上面的代码使用ES2015语法,这是等效的ES5语法:

var months = birthData.reduce(function(accumulator, item) { 
  return accumulator.indexOf(item.month) > -1
    ? accumulator 
    : accumulator.concat(item.month);
}, []);

答案 1 :(得分:2)

您可以将月份映射回新数组,然后使用仅包含唯一值的Set,以使数组唯一而无需自己迭代

var months = [...new Set(birthData.map(i => i.month))]

&#13;
&#13;
var birthData = [{
    "year": 1967,
    "month": "January",
    "births": 31502
  },
  {
    "year": 1967,
    "month": "January",
    "births": 26703
  },
  {
    "year": 1967,
    "month": "February",
    "births": 28853
  },
  {
    "year": 1967,
    "month": "February",
    "births": 26958
  },
  {
    "year": 1967,
    "month": "February",
    "births": 28591
  },
  {
    "year": 1967,
    "month": "March",
    "births": 29545
  },
  {
    "year": 1967,
    "month": "March",
    "births": 30086
  }
]

var months = [...new Set(birthData.map(i => i.month))]

console.log(months)
&#13;
&#13;
&#13;

答案 2 :(得分:1)

const months = birthData.map(month=>month.month);
const result = months.filter((item,pos)=>months.indexOf(item) === pos);