从日期的对象数组中隔离月份,并根据日期对应的月份进行分类

时间:2018-08-24 19:54:09

标签: javascript object ecmascript-6 set

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

预期的newObject是:

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 :(得分:1)

我将使用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)

答案 1 :(得分:0)

有几种方法可以解决此问题,甚至可能包括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]];       
});

答案 2 :(得分:0)

您可以获取对象的条目,并使用简单的保护运算符,即logical OR ||来检查是否已设置属性(是truthy)(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; }