Выделите месяцы из массива объектов и распределите их по месяцам в соответствии с датами. - PullRequest
0 голосов
/ 24 августа 2018
let dates = {
              '2018/07/25': [['r','red'], ['b','blue']],
              '2018/07/26': [['a','apple'], ['o','orange']],
              '2018/08/01': [['d','deer'], ['l','lion']]
            } 

Ожидается новый объект:

newObject = {
             '2018/07':{
                         '2018/07/25': [['r','red'], ['b','blue']],
                         '2018/07/26': [['a','apple'], ['o','orange']]
                       },
             '2018/08':{
                         '2018/08/01': [['d','deer'], ['l','lion']]
                       }

Мой код пока:

let newObject = {};

Object.keys(dates).forEach((onedate, index) => {
    let monthdate = onedate.slice(0,7)
    newObject[monthdate] = {[onedate] : [...dates[onedate]]};       
});

Вывод вышеуказанного кода:

newObject = {
             '2018/07':{
                         '2018/07/26': [['a','apple'], ['o','orange']]
                       },
             '2018/08':{
                         '2018/08/01': [['d','deer'], ['l','lion']]
                       }

последняя дата перезаписывает верхние объекты в том же цикле

Возможно ли выполнить эту операцию в одной функции цикла?Должен ли я использовать наборы?

Ответы [ 3 ]

0 голосов
/ 24 августа 2018

Есть несколько способов решить эту проблему, некоторые, возможно, даже включают Set.

Однако, используя ваш код в качестве отправной точки, ответ довольно прост: не перезаписывайте newObject[monthdate], если он уже существует.

let newObject = {};

Object.keys(dates).forEach((onedate, index) => {
    let monthdate = onedate.slice(0,7)
    if (!newObject[monthdate]) {
        newObject[monthdate] = {};
    }
    newObject[monthdate][onedate] = [...dates[onedate]];       
});
0 голосов
/ 24 августа 2018

Вы можете взять записи объекта и взять простой оператор охраны, логическое ИЛИ || для проверки, установлено ли свойство (является правдивым ) или нет( falsy ).Если нет, возьмите объект в качестве значения по умолчанию.Затем присвойте свойство.

Истинными значениями являются объекты, массивы, непустые строки или все числа без нуля или NaN.

let dates = { '2018/07/25': [['r', 'red'], ['b', 'blue']], '2018/07/26': [['a', 'apple'], ['o', 'orange']], '2018/08/01': [['d', 'deer'], ['l', 'lion']] },
    newObject = {};

Object.entries(dates).forEach(([key, value]) => {
    let monthdate = key.slice(0, 7);
    newObject[monthdate] = newObject[monthdate] || {};
    newObject[monthdate][key] = value;
});

console.log(newObject);
.as-console-wrapper { max-height: 100% !important; top: 0; }
0 голосов
/ 24 августа 2018

Я бы написал это, используя Array.reduce для создания конечного объекта.

var dates = {
  '2018/07/25': [
    ['r', 'red'],
    ['b', 'blue']
  ],
  '2018/07/26': [
    ['a', 'apple'],
    ['o', 'orange']
  ],
  '2018/08/01': [
    ['d', 'deer'],
    ['l', 'lion']
  ]
}

var result = Object.keys(dates).reduce((mem, cur) => {
  var key = cur.slice(0, 7);
  mem[key] = { ...(mem[key] || {}),
    [cur]: dates[cur]
  };
  return mem;
}, {});

console.log(result);

Ваш код не дает правильного результата, потому что вы забыли объединить свойства при добавлении новых свойств.Смотрите, когда вы делаете { [onedate] : [...dates[onedate]] }, здесь вам нужно объединить старые записи также, как я делал ниже.

newObject[monthdate] = {...newObject[monthdate], [onedate] : [...dates[onedate]]};

Ваш код после исправления:

var dates = {
  '2018/07/25': [
    ['r', 'red'],
    ['b', 'blue']
  ],
  '2018/07/26': [
    ['a', 'apple'],
    ['o', 'orange']
  ],
  '2018/08/01': [
    ['d', 'deer'],
    ['l', 'lion']
  ]
}

var newObject = {};

Object.keys(dates).forEach((onedate, index) => {
  var monthdate = onedate.slice(0, 7)
  newObject[monthdate] = { ...newObject[monthdate],
    [onedate]: [...dates[onedate]]
  };
});

console.log(newObject)
...