3 回答
TA贡献1859条经验 获得超6个赞
假设数组的格式是正确的:
const yourArray = ["14:00-14:30", "14:30-15:00", "15:30-16:00"];
const solution = yourArray.sort().reduce(
(acc, item, index) => {
if (index===0) {
acc.push(item);
return acc;
}
const currentValueParsed = acc[acc.length-1].split('-');
const newValueParsed = item.split('-');
if (currentValueParsed[1] === newValueParsed[0]) {
acc[acc.length-1] = `${currentValueParsed[0]}-${newValueParsed[1]}`;
return acc;
}
acc.push(item);
return acc;
}, []
);
console.log(solution); // ["14:00-15:00", "15:30-16:00"]
代码可能很小,但我更喜欢明确。
我们对数组进行排序。
我们将第一个元素添加到最终数组中。
并且每个新元素,ee 决定我们是否需要修改解决方案数组的最后一个元素或将新元素添加到这个数组中。
并且因为您看起来对改进您的原始解决方案感兴趣。
const yourArray = ["14:00-14:30", "14:30-15:00", "15:30-16:00"];
const solution = yourArray.sort()
.join('-')
.split('-')
.filter((item, pos, arr) => {
return pos === 0 || (item !== arr[pos - 1] && item !== arr[pos + 1]);
})
.reduce((acc, item, pos, arr) => {
if (pos % 2) {
acc.push(`${arr[pos - 1]}-${arr[pos]}`);
}
return acc;
}, []);
console.log(solution); // ["14:00-15:00", "15:30-16:00"]
笔记:
在开始时进行排序很重要。
pos % 2 告诉我这是否是一个均匀的位置。
我不在乎arr[pos + 1]在最后一项中返回未定义。
TA贡献2003条经验 获得超2个赞
过滤器不起作用,因为您正在创建一个新值,而不仅仅是保留现有值。不过,减少会。
let start = null, end = null;
let finalAnswer = arr.reduce((result, current, i) => {
const [first, last] = current.split('-');
if (start === null) { start = first;}
if (first !== end && end !== null) { result.push(`${start}-${end}`); if (i === arr.length - 1) { result.push(current); }}
else if (i === arr.length - 1) { result.push(`${start}-${last}`); }
else { end = last; }
return result;
}, []);
我确信有一种更清洁的方法可以做到这一点——我不得不投入比我想要的更多的边缘案例——但这很有效:)
这个想法是您跟踪间隔的开始和结束时间;如果当前间隔的开始等于最后一个间隔的结束,则将结束时间更新为当前间隔的。否则,按下当前开始和结束时间并为下一个条目重置计数器。当最终条目创建或不创建自己的新区间时,将处理边缘情况;如果是,则将条目作为其自己的间隔推送,如果不是,则使用当前开始和条目的结束时间推送一个新间隔。
TA贡献1831条经验 获得超10个赞
这实际上是一个减少操作,因此解决方案可能如下:
const result = array
.sort() // if needed?
.map(tf => tf.split('-')) // make it easier to work with
.reduce((acc, currFrame, idx, arr) => {
let reducedFrame = acc[acc.length - 1] // get latest reduced frame
if (!reducedFrame || reducedFrame.length === 2) { // filled range or at start
reducedFrame = [currFrame[0]] // so start a new one
acc.push(reducedFrame)
}
const nextFrame = arr[idx + 1]
if (!nextFrame || nextFrame[0] !== currFrame[1]) { // at last frame or end of the current continuous frame
reducedFrame.push(currFrame[1]) // so end the reduced frame
}
return acc
}, [])
.map(tf => tf.join('-')) // put it back
或者我相信,在@Dalorzo的基础上,欺骗过滤器方法也会起作用:
const result = array
.join('-').split('-') // convert to array of singles
.filter((v,i) => array.indexOf(v) === i) // lose the dupes
.sort() // if needed (performs better here in this case)
.reduce((acc, cur, i, arr) => // join every 2
(i % 2 === 0)
? acc.concat([cur + '-' + arr[i + 1]])
: acc, [])
添加回答
举报