如何根据另一个对象中相对值的特定顺序为对象分配值?

时间:2018-08-07 19:31:11

标签: javascript momentjs

我正在尝试编写一个函数,该函数将使键值对的对象变异,该键值对代表一年中的每个月以及每个月中的周数。输入示例如下所示,其中每个键分别是月份和年份,而相应的值是该月份中的周数:

 { '2018-01': 4, '2018-02': 4, '2018-03': 4, '2018-04': 5 ... }

目标是根据“ 4-5-4”模式(如果您听说过零售日历,就知道我在说什么)来设置每月的周数。可选参数,以在用户决定的任何月份启动模式。因此,如果用户确定2月为他们的开始月份,则上述对象将转换为:

{ '2018-01': 4 '2018-02': 4, '2018-03': 5, '2018-04': 4 ... }

您可以想象在第四个键值对之后,“ 4-5-4”的模式再次重复。我正在使用moment.js将用户值的输入解析为日期(开始月份的可选参数是“ February”之类的输入)。我发现最棘手的部分是,按照输入日历上出现的月份顺序对输入对象进行迭代,从而充分了解对象并不是固有地有序的。我可以看到一个遥远的MVP,它包含许多嵌套的条件和循环,但是我敢肯定必须有一个更有效的解决方案。

我所做的一次尝试是这样的,我导入了一个月份名称数组,以确保在循环遍历对象时进行有序的迭代:

if (weeksFormat === '4-4-5') {
    for (let i = orderedMonthNames.indexOf(startMonth); i < orderedMonthNames.length; i += 3) {
        months[moment(orderedMonthNames[i]).format('YYYY-M')] = 4
        months[moment(orderedMonthNames[i + 1]).format('YYYY-M')] = 4
        months[moment(orderedMonthNames[i + 2]).format('YYYY-M')] = 5

        for (let x = i - 1; x >= 0; x -= 3) {
            months[moment(orderedMonthNames[x]).format('YYYY-M')] = 4
            months[moment(orderedMonthNames[x - 1]).format('YYYY-M')] = 4
            months[moment(orderedMonthNames[x - 2]).format('YYYY-M')] = 5
        }
    }
}

1 个答案:

答案 0 :(得分:1)

您应该注意以下几点:

  • 您想要的对象键不可排序且对象不可迭代 为此使用数组
  • 您应该避免对对象进行变异

如果我了解问题,则可以采用其他方法: 拥有所有月份的排序数组:

const months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec',];

使用函数从可选的startMonth

开始重新安排月份
function rearrange(startMonth) {
  const index = months.indexOf(startMonth);
  const before = months.slice(0, index);
  const after = months.slice(index);
  return [].concat(after, before);
}

使用它

rearrange(‘Feb’);
// ["Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Jan"]

现在您可以简单地对此进行迭代并使用4-5-4模式,因为它是3的倍数,您可以使用remainder operator

const monthly = {};
const rearrangeed = rearrange('Feb');
rearrangeed.forEach(function(month, index) {
  monthly[month] = (index%3 === 1) ? 5 : 4;
});

console.log(monthly)
// {Feb: 4, Mar: 5, May: 4, Jun: 4, Jul: 5, ... }

最后,再次使用订购的months数组,您可以生成所有需要的最终数组

const ordered = [];
months.forEach(function(monthName, index) {
  const weeks = monthly[monthName];
  const month = moment(monthName).format('YYYY-MM');
  ordered.push({ month, weeks });
});

console.log(ordered);
// [{month: "2018-01", weeks: 4}, {month: "2018-02", weeks: 4}, {month: "2018-03", weeks: 5} … ];

这对您有意义吗?