为什么我在以下JavaScript操作中获得重复值?

时间:2017-08-15 02:32:23

标签: javascript

我有一个名称为星期几天的对象作为键,其值是一个对象数组,其中包含有关不同班次的开始和结束时间的信息。

let openingTimes = 
{
    sunday: [
        { id: 1, shift: 'morning', opening_time: '07:00', closing_time: '11:00' },
        { id: 1, shift: 'day',    opening_time: '13:30', closing_time: '16:30' },
        { id: 1, shift: 'night', opening_time: '20:00', closing_time: '23:00' }
    ],
    monday: [
        { id: 1, shift: 'day',    opening_time: '13:30', closing_time: '16:30' }
    ],
    wednesday: [
        { id: 1, shift: 'morning', opening_time: '07:00', closing_time: '12:00' },
        { id: 1, shift: 'night', opening_time: '20:00', closing_time: '23:00' }
    ],
    thursday: [
        { id: 1, shift: 'morning', opening_time: '07:00', closing_time: '12:00' },
        { id: 1, shift: 'night', opening_time: '20:00', closing_time: '23:00' }
    ],
    friday: [
        { id: 1, shift: 'day',    opening_time: '13:30', closing_time: '16:30' },
        { id: 1, shift: 'night', opening_time: '20:00', closing_time: '23:00' }
    ],
};

我试图对JSON数据进行一些小改动。对于天名称的值,我试图添加其键是移位的对象,值是从开始时间到关闭时间的时间数组,它们之间的差异为15分钟。

enter image description here

虽然我确实成功建立了这个列表,但是我无法弄清楚为什么我会在所有日子里获得完全相同的值。我在某处遗漏了一些简单的东西。

enter image description here

这是我的代码。

let Object1 = {};
let Object2 = {};

for (let key in openingTimes)
{
    openingTimes[key].forEach(item =>
    {
         /* Separate opening time to parts by colon */
        let oParts = item.opening_time.split(':');
        let oHour = oParts[0];
        let oMins = oParts[1];

        /* Separate closing time to parts by colon */
        let cParts = item.closing_time.split(':');
        let cHour = cParts[0];
        let cMins = cParts[1];

        Object1[item.shift] = buildTimeArray(oHour, oMins, cHour, cMins, 15);

        Object2[key] = Object1;
    });
}

console.log(Object2);

/**
 * Gather restaurant hours and return the array of available delivery times in difference of specified minutes
 * @params  Opening Hour, Opening Minutes, Closing Hour, Closing Minutes, Miutes Interval
 */
function buildTimeArray(oHour, oMins, cHour, cMins, interval_mins)
{
    let result = [];
    let start = new Date('','','',oHour, oMins);
    let end = new Date('','','',cHour, cMins);
    for (let d = start; d <= end; d.setMinutes(d.getMinutes() + interval_mins))
    {
        result.push(this.meridianTime(d));
    }
    return result;
}

/**
 * Build time in 12 hrs AM/PM format
 */
function meridianTime(inputDate)
{
    let hours = inputDate.getHours();
    let minutes = inputDate.getMinutes();
    let ampm = hours < 12 ? "AM" : (hours = hours % 12, "PM");

    hours =  hours === 0 ? 12 : hours < 10? ("0" + hours) : hours;
    minutes = minutes < 10 ? ("0" + minutes) : minutes;
    return hours + ":" + minutes + " " + ampm;
}

2 个答案:

答案 0 :(得分:1)

我采用了更实用的方法。

当您有一个需要转换为另一个数据列表的数据列表时,我认为mapfilterreduce是要走的路。

This is a decent video that explains the idea

希望这很有趣。

&#13;
&#13;
let openingTimes = {
  sunday: [{
      id: 1,
      shift: 'morning',
      opening_time: '07:00',
      closing_time: '11:00'
    },
    {
      id: 1,
      shift: 'day',
      opening_time: '13:30',
      closing_time: '16:30'
    },
    {
      id: 1,
      shift: 'night',
      opening_time: '20:00',
      closing_time: '23:00'
    }
  ],
  monday: [{
    id: 1,
    shift: 'day',
    opening_time: '13:30',
    closing_time: '16:30'
  }],
  wednesday: [{
      id: 1,
      shift: 'morning',
      opening_time: '07:00',
      closing_time: '12:00'
    },
    {
      id: 1,
      shift: 'night',
      opening_time: '20:00',
      closing_time: '23:00'
    }
  ],
  thursday: [{
      id: 1,
      shift: 'morning',
      opening_time: '07:00',
      closing_time: '12:00'
    },
    {
      id: 1,
      shift: 'night',
      opening_time: '20:00',
      closing_time: '23:00'
    }
  ],
  friday: [{
      id: 1,
      shift: 'day',
      opening_time: '13:30',
      closing_time: '16:30'
    },
    {
      id: 1,
      shift: 'night',
      opening_time: '20:00',
      closing_time: '23:00'
    }
  ],
};

const fifteenMinutes = new Date('1970-01-01 00:15:00') - new Date('1970-01-01 00:00:00');

// notice the single assignment and no for-loops
const transformedOpeningTimes = (Object
  // grab the keys
  .keys(openingTimes)
  // map to tuples of key values
  .map(dayOfTheWeek => ({
    dayOfTheWeek,
    times: openingTimes[dayOfTheWeek]
  }))
  // map the values to `shifts`
  .map(({
    dayOfTheWeek,
    times
  }) => ({
    dayOfTheWeek,
    // for each time, reduce into the `shifts` object
    shifts: times.reduce((shifts, time) => {
      const {
        opening_time,
        closing_time,
        shift
      } = time;
      const lower = new Date(`1970-01-01 ${opening_time}`).getTime();
      const upper = new Date(`1970-01-01 ${closing_time}`).getTime();
      // calculate how many interval we need
      const intervals = parseInt((upper - lower) / fifteenMinutes);
      shifts[shift] = (Array(intervals)
        // create an array with the same length of intervals
        .fill(0)
        // map them to dates
        .map((_, index) => new Date(index * fifteenMinutes + lower))
        // map the dates to time strings
        .map(date => date.toTimeString())
        // convert the time strings to other time strings
        .map(dateString => {
          const hours = parseInt(dateString.slice(0, 2));
          const amOrPm = hours > 12 ? 'AM' : 'PM';
          return `${hours % 12}:${dateString.slice(3, 5)} ${amOrPm}`;
        })
      );
      return shifts;
    }, {})
  }))
  // reduce back into the object
  .reduce((transformedOpeningTimes, {
    dayOfTheWeek,
    shifts
  }) => {
    transformedOpeningTimes[dayOfTheWeek] = shifts;
    return transformedOpeningTimes;
  }, {})
);

console.log(transformedOpeningTimes);
&#13;
&#13;
&#13;

答案 1 :(得分:0)

对象在JavaScript中通过引用传递,因此您每次都有效地添加相同的对象。

&#13;
&#13;
let openingTimes = {
  sunday: [{
      id: 1,
      shift: 'morning',
      opening_time: '07:00',
      closing_time: '11:00'
    },
    {
      id: 1,
      shift: 'day',
      opening_time: '13:30',
      closing_time: '16:30'
    },
    {
      id: 1,
      shift: 'night',
      opening_time: '20:00',
      closing_time: '23:00'
    }
  ],
  monday: [{
    id: 1,
    shift: 'day',
    opening_time: '13:30',
    closing_time: '16:30'
  }],
  wednesday: [{
      id: 1,
      shift: 'morning',
      opening_time: '07:00',
      closing_time: '12:00'
    },
    {
      id: 1,
      shift: 'night',
      opening_time: '20:00',
      closing_time: '23:00'
    }
  ],
  thursday: [{
      id: 1,
      shift: 'morning',
      opening_time: '07:00',
      closing_time: '12:00'
    },
    {
      id: 1,
      shift: 'night',
      opening_time: '20:00',
      closing_time: '23:00'
    }
  ],
  friday: [{
      id: 1,
      shift: 'day',
      opening_time: '13:30',
      closing_time: '16:30'
    },
    {
      id: 1,
      shift: 'night',
      opening_time: '20:00',
      closing_time: '23:00'
    }
  ],
};

let Object2 = {};

for (let key in openingTimes) {

  let Object1 = {};

  openingTimes[key].forEach(item => {
    /* Separate opening time to parts by colon */
    let oParts = item.opening_time.split(':');
    let oHour = oParts[0];
    let oMins = oParts[1];

    /* Separate closing time to parts by colon */
    let cParts = item.closing_time.split(':');
    let cHour = cParts[0];
    let cMins = cParts[1];

    Object1[item.shift] = buildTimeArray(oHour, oMins, cHour, cMins, 15);

    Object2[key] = Object1;
  });
}
console.log(Object2);


/**
 * Gather restaurant hours and return the array of available delivery times in difference of specified minutes
 * @params  Opening Hour, Opening Minutes, Closing Hour, Closing Minutes, Miutes Interval
 */
function buildTimeArray(oHour, oMins, cHour, cMins, interval_mins) {
  let result = [];
  let start = new Date('', '', '', oHour, oMins);
  let end = new Date('', '', '', cHour, cMins);
  for (let d = start; d <= end; d.setMinutes(d.getMinutes() + interval_mins)) {
    result.push(this.meridianTime(d));
  }
  return result;
}

/**
 * Build time in 12 hrs AM/PM format
 */
function meridianTime(inputDate) {
  let hours = inputDate.getHours();
  let minutes = inputDate.getMinutes();
  let ampm = hours < 12 ? "AM" : (hours = hours % 12, "PM");

  hours = hours === 0 ? 12 : hours < 10 ? ("0" + hours) : hours;
  minutes = minutes < 10 ? ("0" + minutes) : minutes;
  return hours + ":" + minutes + " " + ampm;
}
&#13;
&#13;
&#13;