Я изучаю d3 в JavaScript и работаю над некоторыми базовыми данными манипулирования данными. У меня есть простой объект 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 сделает мою жизнь намного проще!

0
Canovice 5 Мар 2018 в 03:13

3 ответа

Лучший ответ

Вы можете отобразить месяцы обратно в новый массив, а затем использовать 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
adeneo 5 Мар 2018 в 00:21

Использование 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);
}, []);
2
Lennholm 5 Мар 2018 в 00:46
const months = birthData.map(month=>month.month);
const result = months.filter((item,pos)=>months.indexOf(item) === pos);
1
keithlee96 5 Мар 2018 в 00:22