Генерация объектов дня недели из массива строк - PullRequest
5 голосов
/ 06 мая 2019

У меня есть массив диапазонов дней, например:

["Mon-Tue", "Mon-Wed", "Mon-Thu", "Mon-Fri", "Mon-Sat", "Mon-Sun", "Tue-Mon", "Tue-Wed", "Tue-Thu", "Tue-Fri", "Tue-Sat", "Tue-Sun", ...]

Мне нужно создать большой объект, который отображает каждую из этих строк в массив, содержащий всесоответствующие дни, например:

var object = {
  'Mon-Tue': ['Mon', 'Tue'],
  'Mon-Wed': ['Mon', 'Tue', 'Wed'],
}

Чтобы помочь, у меня есть массив возможных дней:

var days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']

Возможно ли это, не делая все это вручную?

Спасибо!

Ответы [ 5 ]

3 голосов
/ 06 мая 2019

Вы можете взять Map для получения дней с индексом и повторять, пока не получите все дни.

var days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
    daysMap = new Map(days.map((d, i) => [d, i])),
    data = ["Mon-Tue", "Mon-Wed", "Mon-Thu", "Mon-Fri", "Mon-Sat", "Mon-Sun", "Tue-Mon", "Tue-Wed", "Tue-Thu", "Tue-Fri", "Tue-Sat", "Tue-Sun"],
    result = Object.assign({}, ...data.map(d => {
        var [start, end] = d.split('-'),
            temp = [],
            s = daysMap.get(start),
            e = daysMap.get(end);

        while (s !== e) {
            temp.push(days[s]);
            s++;
            s %= days.length
        }
        temp.push(days[s]);
        return { [d]: temp };
    }));

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

Если хотите, вы можете взять Generator на требуемые дни.

function* getDays(from, to) {
    var days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
        i = days.indexOf(from);

    while (days[i % days.length] !== to) yield days[i++ % days.length];
    yield days[i % days.length];
}

var data = ["Fri-Tue", "Mon-Tue", "Mon-Wed", "Mon-Thu", "Mon-Fri", "Mon-Sat", "Mon-Sun", "Tue-Mon", "Tue-Wed", "Tue-Thu", "Tue-Fri", "Tue-Sat", "Tue-Sun"],
    result = Object.assign({}, ...data.map(d => ({ [d]: [...getDays(...d.split('-'))] })));

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

Другой подход с использованием объекта завтрашнего дня, который дает день завтрашнего дня.

function* getDays(from, to) {
    var tomorrow = { Sun: 'Mon', Mon: 'Tue', Tue: 'Wed', Wed: 'Thu', Thu: 'Fri', Fri: 'Sat', Sat: 'Sun' };

    yield from;
    while (from !== to) yield from = tomorrow[from];
}

var data = ["Fri-Tue", "Mon-Tue", "Mon-Wed", "Mon-Thu", "Mon-Fri", "Mon-Sat", "Mon-Sun", "Tue-Mon", "Tue-Wed", "Tue-Thu", "Tue-Fri", "Tue-Sat", "Tue-Sun"],
    result = Object.assign({}, ...data.map(d => ({ [d]: [...getDays(...d.split('-'))] })));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
2 голосов
/ 06 мая 2019

Вы можете создать массив days.Сначала split диапазон и получаем индексы текущего диапазона.

  • Если toIndex > fromIndex, используйте slice, чтобы получить часть массива.

  • Если fromIndex > toIndex:

    • Получить массив от fromIndex до конца days массива
    • Plus,от 0 до toIndex

const array = ["Mon-Tue", "Mon-Wed", "Mon-Thu", "Mon-Fri", "Mon-Sat", "Mon-Sun", "Tue-Mon", "Tue-Wed", "Tue-Thu", "Tue-Fri", "Tue-Sat", "Tue-Sun"]

const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]

const output = {}

array.forEach(range => {
  const [fromIndex, toIndex] = range.split('-').map(a => days.indexOf(a))
  
  if(fromIndex > toIndex)
    output[range] = [...days.slice(fromIndex), ...days.slice(0, toIndex + 1)]
  else
    output[range] = days.slice(fromIndex, toIndex + 1)
})

console.log(output)
.as-console-wrapper { max-height: 100% !important; top: 0; }
1 голос
/ 06 мая 2019

Вы можете сделать это в следующих шагах:

  • Применить reduce() массив строк, содержащих диапазоны, и установить аккумулятор в пустой объект {}
  • Затем split()строка на -.
  • Получите indexOf() каждый день в массиве days.
  • Затем используйте slice() на days, предоставив ему индексы первого ивторая часть строки соответственно.
  • Установить для них строку как новую key и ее значение в массиве, возвращаемое slice()

let arr =  ["Mon-Tue", "Mon-Wed", "Mon-Thu", "Mon-Fri", "Mon-Sat", "Mon-Sun", "Tue-Mon", "Tue-Wed", "Tue-Thu", "Tue-Fri", "Tue-Sat", "Tue-Sun"]

var days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']

let res = arr.reduce((ac,x) => {
  let temp = x.split('-').map(a => days.indexOf(a));
  ac[x] = days.slice(temp[0],temp[1]+1);
  return ac;
},{})

console.log(res)
0 голосов
/ 06 мая 2019

Самый простой - создать массив с повторяющимися днями.

let input = ["Fri-Tue", "Mon-Wed", "Mon-Thu", "Mon-Fri", "Mon-Sat", "Mon-Sun", "Tue-Mon", "Tue-Wed", "Tue-Thu", "Tue-Fri", "Tue-Sat", "Tue-Sun"];
let days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
let daysArr = [...days, ...days];

let out = {};

input.forEach((e) => {
	if(!out[e]) {
		out[e] = getDays(e);
	}
});

function getDays(str) {
	let [from, to] = str.split('-').map(e => days.indexOf(e));
	to = from < to ? to : to+7
	return daysArr.slice(from, to+1);
}

console.log(out)
0 голосов
/ 06 мая 2019

    let arr =  ["Mon-Tue", "Mon-Wed", "Mon-Thu", "Mon-Fri", "Mon-Sat", "Mon-Sun", "Tue-Mon", "Tue-Wed", "Tue-Thu", "Tue-Fri", "Tue-Sat", "Tue-Sun"];
    var days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
    
    var result = {};

    arr.map((x) => {

      var splitedArr = x.split('-');

      //left day < right day
      if (days.indexOf(splitedArr[0]) < days.indexOf(splitedArr[1]) + 1){
        var slicedDays = days.slice(days.indexOf(splitedArr[0]),days.indexOf(splitedArr[1]) + 1);
      }
      else{//left day > right day
        var slicedDays = days.slice(days.indexOf(splitedArr[0]),days.length);
        slicedDays = slicedDays.concat(days.slice(0,days.indexOf(splitedArr[1]) + 1));
      }

      result[x] = slicedDays;

    });
    
    console.log(result);
...