javascript - javascript - 从字符串数组生成星期几的对象

我有天范围的数组,如下所示:

[" 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']



如果不手动去做,可能完成这一切吗?

谢谢!

时间:

你可以拿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; }

你可以创建一个days数组,首先,split范围,并且获取当前范围的索引。

  • 如果为toIndex> fromIndex,则使用 slice获取数组的一部分。

  • 如果fromIndex> toIndex:

    • fromIndex获取数组直到days数组的末尾,
    • 另外从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; }

你可以按照以下步骤进行操作:

  • 应用reduce()数组包含范围的字符串并将累加器设置为空对象{}
  • 然后用-将字符串split()
  • 获取indexOf()每天inside数组,
  • 然后通过为days分别提供字符串的第一和第二部分的索引,对使用slice()
  • 将它们设置为新的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)
 

 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);

我把这个问题分成两个部分

  • 给定一组日期,准备${aDay}-${anotherDay}的列表,${anotherDay}总是在${aDay}之后,
  • 给定一个字符串格式的字符串准备一个对象该对象将是${aDay}-${anotherDay}的数组,

解决第一个问题:

 

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



const daysRange = days


 . map((aDay, anIndex) => {


 /**


 * For each day, again do a. map() on days and prepare an array of `${aDay}-${anotherDay}`


 */


 return days.map((anotherDay, anotherIndex) => {


 /**


 * index of ${anotherDay} should always be greater than index of ${aDay}


 * So that 'Mon-Tue', 'Mon-Wed',. .. can be prepared


 */


 if (anotherIndex> anIndex) {


 return `${aDay}-${anotherDay}`;


 }


 /** Return null, We will filter it later. */


 return null;


 });


 })


 /**


 * Out of that. map() is an array of arrays.


 * We can join all the inner arrays to create one array using. reduce()


 */


 . reduce((preparedArray, currentArray) => {


 return preparedArray.concat(...currentArray);


 }, [])


 /**


 * Once we have one single array, just filter out the nulls


 */


 . filter(aDayRange =>!!aDayRange);



console.log(daysRange);



注意.map(days)O(n^2),但是,只要数组中只有7个元素,这就不重要了,用.map()和其他标准数组方法在我认为循环中进行循环。

解决第二个问题的方法更容易。

 

const regex =/(.*)-(.*)/;


const map = daysRange.reduce((preparedMap, currentRange) => {


 const matched = currentRange.match(regex);


 if (matched) {


 const dayStart = matched[1];


 const dayEnd = matched[2];


 /** We would need the indices of both the days to determine which days would be included */


 const dayStartIndex = days.indexOf(dayStart);


 const dayEndIndex = days.indexOf(dayEnd);


 const daysBetween = days


 . map((aDay, index) => {


 /** aDay would be included if the index of it is in between dayStartIndex and dayEndIndex*/


 if (dayStartIndex <= index && index <= dayEndIndex) {


 return aDay;


 }


 return null;


 })


 /** Filter out the nulls */


 . filter(aDay =>!!aDay);


 preparedMap[currentRange] = daysBetween;


 return preparedMap;


 }


 return preparedMap;


}, {});



console.log(map);



在这里,map就是你想要的。

以下是完整的代码段:

 

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



const daysRange = days


 . map((aDay, anIndex) => {


 /**


 * For each day, again do a. map() on days and prepare an array of `${aDay}-${anotherDay}`


 */


 return days.map((anotherDay, anotherIndex) => {


 /**


 * index of ${anotherDay} should always be greater than index of ${aDay}


 * So that 'Mon-Tue', 'Mon-Wed',. .. can be prepared


 */


 if (anotherIndex> anIndex) {


 return `${aDay}-${anotherDay}`;


 }


 /** Return null, We will filter it later. */


 return null;


 });


 })


 /**


 * Out of that. map() is an array of arrays.


 * We can join all the inner arrays to create one array using. reduce()


 */


 . reduce((preparedArray, currentArray) => {


 return preparedArray.concat(...currentArray);


 }, [])


 /**


 * Once we have one single array, just filter out the nulls


 */


 . filter(aDayRange =>!!aDayRange);



const regex =/(.*)-(.*)/;


const map = daysRange.reduce((preparedMap, currentRange) => {


 const matched = currentRange.match(regex);


 if (matched) {


 const dayStart = matched[1];


 const dayEnd = matched[2];


 /** We would need the indices of both the days to determine which days would be included */


 const dayStartIndex = days.indexOf(dayStart);


 const dayEndIndex = days.indexOf(dayEnd);


 const daysBetween = days


 . map((aDay, index) => {


 /** aDay would be included if the index of it is in between dayStartIndex and dayEndIndex*/


 if (dayStartIndex <= index && index <= dayEndIndex) {


 return aDay;


 }


 return null;


 })


 /** Filter out the nulls */


 . filter(aDay =>!!aDay);


 preparedMap[currentRange] = daysBetween;


 return preparedMap;


 }


 return preparedMap;


}, {});



console.log(map);



最简单的方法是创建具有重复天数的数组。

 

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)
...