使用javascript的reduce方法将对象数组转换为另一个对象

时间:2018-03-11 05:18:15

标签: javascript ecmascript-6

我需要将事件添加到现有日期,所以我认为我需要更改我的json结构,如下所示。我尝试通过reduce实现它,如下所示

我想转换这个对象数组

    {  
   "sunday":[  
      {  
         "7":[  
            "event1",
            "event2",
            "event3"
         ]
      },
      {  
         "14":[  
            "event3",
            "event4",
            "event5"
         ]
      },
      {
          "21":[]
      },
      {
          "28":[]
      }
   ]
}

{
    "data": [
       { "date": "7", 
         "events": ["event1", "event2", "event3"] 
       },
       { "date": "14", 
         "events": ["event3", "event4", "event5"] 
       },
]
}

以下是包含事件详细信息的数据

attachEventsToTheDate(week_days) {
    var answer = [week_days].reduce(function(result, item, index) {
      var key = Object.keys(item)[0];
      var value = item[key][index];
      var obj = {};
      obj[key] = [obj[key]];
      console.log('obj is', JSON.stringify(obj));
      // JSON.stringify(obj);
      // result.push(obj);
      return result;
    }, {}); //an empty array
  }

我尝试过但失败了,

{{1}}

2 个答案:

答案 0 :(得分:0)

您希望拥有的对象结构使用起来效率不高,但现在是:

function groupEvents(week_days, events) {
    const numToDay = []; // Extra index into the week_days nested objects
    // Create a new week_days object
    week_days = Object.assign(...Object.keys(week_days).map( day => 
        ({ [day]: week_days[day].filter(Number).map(num => 
            ({ [num]: numToDay[num] = [] })
        )})
    ));
    // Inject the events data into it
    for (const data of events.data) {
        // Skip if this day does not exist in the original week_days structure
        if (!numToDay[data.date]) continue;
        numToDay[data.date].push(...data.events);
    }
    return week_days;
}

const week_days = {sunday: ["...", 7, 14, 21, 28]},
      events = {data: [
          { date:  "7", events: ["event1", "event2", "event3"] },
          { date: "14", events: ["event4", "event5"] } 
      ]};

const res = groupEvents(week_days, events);
console.log(res);
.as-console-wrapper { max-height: 100% !important; top: 0; }

更通用的解决方案

week_days对象似乎是某个月的翻译。如果只有一个月,则可以从中导出week_days结构。所以关键信息实际上是你的events对象。如果您可以将该对象(在原始问题中指定,即包含年份和月份信息)转换为按年 - 月组合分组的内容,然后为每个组合生成week_days那种结构,你将拥有你所需要的一切。

同时,将day数字用作week_days嵌套对象中的键似乎更合乎逻辑。

这是一个关于如何做到这一点的演示:

const events = {
    "data": [
       { "year": "2017", "month": "january", "date": "16", 
         "events": ["event1", "event2", "event3"] 
       },
       { "year": "2017", "month": "january", "date": "8", 
         "events": ["event4", "event5"] 
       },
    ]
};

function groupEvents(events) {
    const dayNames = ['sunday', 'monday', 'tuesday', 'wednesday', 
                      'thursday', 'friday', 'saturday']; 
    return events.data.reduce( (acc, o) => {
        const key = o.month.toLowerCase() + " " + o.year;
        if (!acc[key]) {
            acc[key] = Object.assign(...dayNames.map(day => ({ [day]: {} })));
            const dt = new Date("1 " + key);
            const month = dt.getMonth();
            while (dt.getMonth() === month) {
                acc[key][dayNames[dt.getDay()]][dt.getDate()] = [];
                dt.setDate(dt.getDate()+1);
            }
        }
        const dt = new Date(o.date + " " + key);
        acc[key][dayNames[dt.getDay()]][dt.getDate()].push(...o.events);
        return acc;
    }, {});
}
const res = groupEvents(events);
console.log(res);
.as-console-wrapper { max-height: 100% !important; top: 0; }

如果您现在只想拥有2017年1月的数据(例如),您可以将其从上述脚本的结果中取出,如下所示:

const january2017_week_days = res["january 2017"]; 

答案 1 :(得分:0)

map它:



var sunday = [ 7, 14, 21, 28 ]
var data = [ { "date": "7", "events": ["event1", "event2", "event3"] }, { "date": "14", "events": ["event3", "event4", "event5"] }]

console.log(sunday.map(x => {
    var actual = data.find(y => y.date == x);
    if(actual) {
        return {[x]: actual.events}
    } else {
        return {[x]: []}
    }
}))

.as-console-wrapper { max-height: 100% !important; top: 0; }




相关问题