如何根据常见的子字符串模式减少和 mutate/change 数组的字符串条目?
How does one reduce and mutate/change string entries of an array based on common substring patterns?
我有一个字符串项数组...
[
'Mon : 9:00AM - 7:00PM',
'Tue : 9:00AM - 10:00PM',
'Wed : Closed',
'Thu : 9:00AM - 7:00PM',
'Fri : 9:00AM - 7:00PM',
'Sat : Closed',
'Sun : Closed',
]
...我想达到如下所示的结果...
[
'Mon: 9:00AM - 7:00PM',
'Tue: 9:00AM - 10:00PM',
'Wed: Closed',
'Thu-Fri: 9:00AM - 7:00PM',
'Sat-Sun: Closed',
]
非常感谢任何帮助。
首先需要将单个开放时间字符串的 day
值与 hours
值部分分开。
这可以通过 indexOf
, substring
and trim
...
实现
function splitOpeningHoursEntry(entry) {
// e.g.: 'Mon : 9:00AM - 7:00PM'
const indexOfColon = entry.indexOf(':'); // e.g. 5
// entry.substring(0, 5) ... e.g.: 'Mon '
const day = entry.substring(0, indexOfColon);
// entry.substring(6) ... e.g.: ' 9:00AM - 7:00PM'
const hours = entry.substring(indexOfColon + 1);
// e.g.: ['Mon', '9:00AM - 7:00PM']
return [day.trim(), hours.trim()];
}
... 或者可以通过 split
-ting with a Regular Expression like ... /(^[^:\s]+)\s*:\s*/ ... and slice
-ing 结果数组来完成...
function regexSplitOpeningHoursEntry(entry) {
// [https://regex101.com/r/vGRck7/3]
// entry.split(':') // ["Mon ", " 9", "00AM - 7", "00PM"]
// [https://regex101.com/r/vGRck7/2]
// entry.split(/\s*:\s*/) // ["Mon", "9", "00AM - 7", "00PM"]
// [https://regex101.com/r/vGRck7/1]
// entry.split(/(^[^:\s]+)\s*:\s*/) // ["", "Mon", "9:00AM - 7:00PM"];
return entry.split(/(^[^:\s]+)\s*:\s*/).slice(1);
}
然后必须将整个营业时间字符串数组 map
放入一个数组数组中,其中每个数组项包含第一个 day
值和 hours
值作为第二个数组项...或者像这样...
sampleList.map(splitOpeningHoursEntry);
...或类似...
sampleList.map(regexSplitOpeningHoursEntry);
最重要的是需要 reduce
将这个拆分的 [<day>, <hours>]
条目数组转换为紧凑形式 ...
最后必须 map
每个拆分的 [<day>, <hours>]
条目 concatenation task 回到其人类可读的字符串形式....
const sampleList = [
'Mon : 9:00AM - 7:00PM',
'Tue : 9:00AM - 10:00PM',
'Wed : Closed',
'Thu : 9:00AM - 7:00PM',
'Fri : 9:00AM - 7:00PM',
'Sat : Closed',
'Sun : Closed',
];
function splitOpeningHoursEntry(entry) {
// e.g.: 'Mon : 9:00AM - 7:00PM'
const indexOfColon = entry.indexOf(':'); // e.g. 5
// entry.substring(0, 5) ... e.g.: 'Mon '
const day = entry.substring(0, indexOfColon);
// entry.substring(6) ... e.g.: ' 9:00AM - 7:00PM'
const hours = entry.substring(indexOfColon + 1);
// e.g.: ['Mon', '9:00AM - 7:00PM']
return [day.trim(), hours.trim()];
}
function regexSplitOpeningHoursEntry(entry) {
// [https://regex101.com/r/vGRck7/3]
// entry.split(':') // ["Mon ", " 9", "00AM - 7", "00PM"]
// [https://regex101.com/r/vGRck7/2]
// entry.split(/\s*:\s*/) // ["Mon", "9", "00AM - 7", "00PM"]
// [https://regex101.com/r/vGRck7/1]
// entry.split(/(^[^:\s]+)\s*:\s*/) // ["", "Mon", "9:00AM - 7:00PM"];
return entry.split(/(^[^:\s]+)\s*:\s*/).slice(1);
}
function compactOpeningHoursEntries(compactEntries, splitEntry, idx, arr) {
// get the predecessor item of the currently
// processed `splitEntry` item or default to [].
const prevSplitEntry = arr[idx - 1] || [];
// get the successor item of the currently
// processed `splitEntry` item or default to [].
const nextSplitEntry = arr[idx + 1] || [];
if (prevSplitEntry[1] !== splitEntry[1]) {
// in case the previous and current `hours` values do not match ...
// ... push the current entry of splitted `day` and `hours`
// values into `compactEntries` which is the accumulating
// array of the compacted form of all opening hours entries.
compactEntries.push(splitEntry);
} else if (nextSplitEntry[1] !== splitEntry[1]) {
// ... or in case the next and current `hours` values do not match ...
const lastCompactEntry = compactEntries[compactEntries.length - 1];
// ...retrieve the first and the last day value
// of a compactly written day-range format...
const firstDayInRange = lastCompactEntry[0];
const lastDayInRange = splitEntry[0];
// ...and create and rewrite its compact form
// as the compacted entry's final day value.
lastCompactEntry[0] = firstDayInRange + '-' + lastDayInRange;
}
return compactEntries;
}
function concatOpeningHoursEntry([day, hours]) {
return `${ day }: ${ hours }`;
}
// First one needs to separate the `day` from the
// `hours` part of a single opening hours string
console.log(
"splitOpeningHoursEntry('Mon : 9:00AM - 7:00PM') ...",
splitOpeningHoursEntry('Mon : 9:00AM - 7:00PM')
);
console.log(
"regexSplitOpeningHoursEntry('Mon : 9:00AM - 7:00PM') ...",
regexSplitOpeningHoursEntry('Mon : 9:00AM - 7:00PM')
);
// Then one does map an entire array of opening hours strings
// into an array of arrays, where each array item contains the
// `day` value as first and the `hours` value as second array item.
console.log(
'... list item `split` mapping ... ',
sampleList
.map(splitOpeningHoursEntry)
//.map(regexSplitOpeningHoursEntry)
)
// On top one has to `reduce` this array of splitted
// `[<day>, <hours>]` entries into its compact form.
console.log(
'... list item `split` mapping and split entry reducing ... ',
sampleList
.map(splitOpeningHoursEntry)
.reduce(compactOpeningHoursEntries, [])
);
// Finally one needs to `map` each splitted `[<day>, <hours>]` entry
// with a concatenation task back into its human readable string form.
console.log(
'... list item `split` mapping, reducing and a final concatenation mapping ... ',
sampleList
.map(splitOpeningHoursEntry)
.reduce(compactOpeningHoursEntries, [])
.map(concatOpeningHoursEntry)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
另一个不那么多话的概念证明......
function splitOpeningHoursEntry(entry) {
return entry.split(/(^[^:\s]+)\s*:\s*/).slice(1);
}
function concatOpeningHoursEntry([day, hours]) {
return `${ day }: ${ hours }`;
}
function compactOpeningHoursEntries(compactEntries, splitEntry, idx, arr) {
const prevSplitEntry = arr[idx - 1] || [];
const nextSplitEntry = arr[idx + 1] || [];
if (prevSplitEntry[1] !== splitEntry[1]) {
compactEntries.push(splitEntry);
} else if (nextSplitEntry[1] !== splitEntry[1]) {
const lastCompactEntry = compactEntries[compactEntries.length - 1];
const firstDayInRange = lastCompactEntry[0];
const lastDayInRange = splitEntry[0];
lastCompactEntry[0] = firstDayInRange + '-' + lastDayInRange;
}
return compactEntries;
}
console.log([
'Mon : 08:00AM - 17:00PM',
'Tue : 08:00AM - 17:00PM',
'Wed : 08:00AM - 17:00PM',
'Thu : 10:00AM - 14:00PM',
'Fri : 10:00AM - 14:00PM',
'Sat : Closed',
'Sun : Closed',
], '=>', [
'Mon : 08:00AM - 17:00PM',
'Tue : 08:00AM - 17:00PM',
'Wed : 08:00AM - 17:00PM',
'Thu : 10:00AM - 14:00PM',
'Fri : 10:00AM - 14:00PM',
'Sat : Closed',
'Sun : Closed',
]
.map(splitOpeningHoursEntry)
.reduce(compactOpeningHoursEntries, [])
.map(concatOpeningHoursEntry)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
我有一个字符串项数组...
[
'Mon : 9:00AM - 7:00PM',
'Tue : 9:00AM - 10:00PM',
'Wed : Closed',
'Thu : 9:00AM - 7:00PM',
'Fri : 9:00AM - 7:00PM',
'Sat : Closed',
'Sun : Closed',
]
...我想达到如下所示的结果...
[
'Mon: 9:00AM - 7:00PM',
'Tue: 9:00AM - 10:00PM',
'Wed: Closed',
'Thu-Fri: 9:00AM - 7:00PM',
'Sat-Sun: Closed',
]
非常感谢任何帮助。
首先需要将单个开放时间字符串的
day
值与hours
值部分分开。这可以通过
实现indexOf
,substring
andtrim
...function splitOpeningHoursEntry(entry) { // e.g.: 'Mon : 9:00AM - 7:00PM' const indexOfColon = entry.indexOf(':'); // e.g. 5 // entry.substring(0, 5) ... e.g.: 'Mon ' const day = entry.substring(0, indexOfColon); // entry.substring(6) ... e.g.: ' 9:00AM - 7:00PM' const hours = entry.substring(indexOfColon + 1); // e.g.: ['Mon', '9:00AM - 7:00PM'] return [day.trim(), hours.trim()]; }
... 或者可以通过
split
-ting with a Regular Expression like ... /(^[^:\s]+)\s*:\s*/ ... andslice
-ing 结果数组来完成...function regexSplitOpeningHoursEntry(entry) { // [https://regex101.com/r/vGRck7/3] // entry.split(':') // ["Mon ", " 9", "00AM - 7", "00PM"] // [https://regex101.com/r/vGRck7/2] // entry.split(/\s*:\s*/) // ["Mon", "9", "00AM - 7", "00PM"] // [https://regex101.com/r/vGRck7/1] // entry.split(/(^[^:\s]+)\s*:\s*/) // ["", "Mon", "9:00AM - 7:00PM"]; return entry.split(/(^[^:\s]+)\s*:\s*/).slice(1); }
然后必须将整个营业时间字符串数组
map
放入一个数组数组中,其中每个数组项包含第一个day
值和hours
值作为第二个数组项...或者像这样...sampleList.map(splitOpeningHoursEntry);
...或类似...
sampleList.map(regexSplitOpeningHoursEntry);
最重要的是需要
reduce
将这个拆分的[<day>, <hours>]
条目数组转换为紧凑形式 ...最后必须
map
每个拆分的[<day>, <hours>]
条目 concatenation task 回到其人类可读的字符串形式....
const sampleList = [
'Mon : 9:00AM - 7:00PM',
'Tue : 9:00AM - 10:00PM',
'Wed : Closed',
'Thu : 9:00AM - 7:00PM',
'Fri : 9:00AM - 7:00PM',
'Sat : Closed',
'Sun : Closed',
];
function splitOpeningHoursEntry(entry) {
// e.g.: 'Mon : 9:00AM - 7:00PM'
const indexOfColon = entry.indexOf(':'); // e.g. 5
// entry.substring(0, 5) ... e.g.: 'Mon '
const day = entry.substring(0, indexOfColon);
// entry.substring(6) ... e.g.: ' 9:00AM - 7:00PM'
const hours = entry.substring(indexOfColon + 1);
// e.g.: ['Mon', '9:00AM - 7:00PM']
return [day.trim(), hours.trim()];
}
function regexSplitOpeningHoursEntry(entry) {
// [https://regex101.com/r/vGRck7/3]
// entry.split(':') // ["Mon ", " 9", "00AM - 7", "00PM"]
// [https://regex101.com/r/vGRck7/2]
// entry.split(/\s*:\s*/) // ["Mon", "9", "00AM - 7", "00PM"]
// [https://regex101.com/r/vGRck7/1]
// entry.split(/(^[^:\s]+)\s*:\s*/) // ["", "Mon", "9:00AM - 7:00PM"];
return entry.split(/(^[^:\s]+)\s*:\s*/).slice(1);
}
function compactOpeningHoursEntries(compactEntries, splitEntry, idx, arr) {
// get the predecessor item of the currently
// processed `splitEntry` item or default to [].
const prevSplitEntry = arr[idx - 1] || [];
// get the successor item of the currently
// processed `splitEntry` item or default to [].
const nextSplitEntry = arr[idx + 1] || [];
if (prevSplitEntry[1] !== splitEntry[1]) {
// in case the previous and current `hours` values do not match ...
// ... push the current entry of splitted `day` and `hours`
// values into `compactEntries` which is the accumulating
// array of the compacted form of all opening hours entries.
compactEntries.push(splitEntry);
} else if (nextSplitEntry[1] !== splitEntry[1]) {
// ... or in case the next and current `hours` values do not match ...
const lastCompactEntry = compactEntries[compactEntries.length - 1];
// ...retrieve the first and the last day value
// of a compactly written day-range format...
const firstDayInRange = lastCompactEntry[0];
const lastDayInRange = splitEntry[0];
// ...and create and rewrite its compact form
// as the compacted entry's final day value.
lastCompactEntry[0] = firstDayInRange + '-' + lastDayInRange;
}
return compactEntries;
}
function concatOpeningHoursEntry([day, hours]) {
return `${ day }: ${ hours }`;
}
// First one needs to separate the `day` from the
// `hours` part of a single opening hours string
console.log(
"splitOpeningHoursEntry('Mon : 9:00AM - 7:00PM') ...",
splitOpeningHoursEntry('Mon : 9:00AM - 7:00PM')
);
console.log(
"regexSplitOpeningHoursEntry('Mon : 9:00AM - 7:00PM') ...",
regexSplitOpeningHoursEntry('Mon : 9:00AM - 7:00PM')
);
// Then one does map an entire array of opening hours strings
// into an array of arrays, where each array item contains the
// `day` value as first and the `hours` value as second array item.
console.log(
'... list item `split` mapping ... ',
sampleList
.map(splitOpeningHoursEntry)
//.map(regexSplitOpeningHoursEntry)
)
// On top one has to `reduce` this array of splitted
// `[<day>, <hours>]` entries into its compact form.
console.log(
'... list item `split` mapping and split entry reducing ... ',
sampleList
.map(splitOpeningHoursEntry)
.reduce(compactOpeningHoursEntries, [])
);
// Finally one needs to `map` each splitted `[<day>, <hours>]` entry
// with a concatenation task back into its human readable string form.
console.log(
'... list item `split` mapping, reducing and a final concatenation mapping ... ',
sampleList
.map(splitOpeningHoursEntry)
.reduce(compactOpeningHoursEntries, [])
.map(concatOpeningHoursEntry)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
另一个不那么多话的概念证明......
function splitOpeningHoursEntry(entry) {
return entry.split(/(^[^:\s]+)\s*:\s*/).slice(1);
}
function concatOpeningHoursEntry([day, hours]) {
return `${ day }: ${ hours }`;
}
function compactOpeningHoursEntries(compactEntries, splitEntry, idx, arr) {
const prevSplitEntry = arr[idx - 1] || [];
const nextSplitEntry = arr[idx + 1] || [];
if (prevSplitEntry[1] !== splitEntry[1]) {
compactEntries.push(splitEntry);
} else if (nextSplitEntry[1] !== splitEntry[1]) {
const lastCompactEntry = compactEntries[compactEntries.length - 1];
const firstDayInRange = lastCompactEntry[0];
const lastDayInRange = splitEntry[0];
lastCompactEntry[0] = firstDayInRange + '-' + lastDayInRange;
}
return compactEntries;
}
console.log([
'Mon : 08:00AM - 17:00PM',
'Tue : 08:00AM - 17:00PM',
'Wed : 08:00AM - 17:00PM',
'Thu : 10:00AM - 14:00PM',
'Fri : 10:00AM - 14:00PM',
'Sat : Closed',
'Sun : Closed',
], '=>', [
'Mon : 08:00AM - 17:00PM',
'Tue : 08:00AM - 17:00PM',
'Wed : 08:00AM - 17:00PM',
'Thu : 10:00AM - 14:00PM',
'Fri : 10:00AM - 14:00PM',
'Sat : Closed',
'Sun : Closed',
]
.map(splitOpeningHoursEntry)
.reduce(compactOpeningHoursEntries, [])
.map(concatOpeningHoursEntry)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }