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

问题描述 投票:0回答:3

我在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中快速进行数据操作会让我的生活更轻松!

javascript data-manipulation
3个回答
2
投票

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

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

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)

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
投票
const months = birthData.map(month=>month.month);
const result = months.filter((item,pos)=>months.indexOf(item) === pos);
© www.soinside.com 2019 - 2024. All rights reserved.