首页 > 解决方案 > 凝聚一串时间块;显示日期范围

问题描述

用户在预订租赁空间时选择小时数(作为DateTime对象)。

List<DateTime> dateTimeList = getDateTimeList();

我将该列表转换为可呈现的字符串,如下所示:

List<String> hourList = List<String>();

for (DateTime dateTime in dateTimeList) {
  String hour = getHour(dateTime, context); // getHour returns e.g. 14:00 or 2pm
  String nextHour = getHour(dateTime.add(Duration(hours: 1)), context);
  hourList.add(hour + " - " + nextHour);
}

hourList.sort();
return hourList.join(", ");

最终我有以下列表:

10:00 - 11:00
11:00 - 12:00
15:00 - 16:00
16:00 - 17:00
20:00 - 21:00

问:我怎样才能压缩它,以便合并连续的块?像这样:

10:00 - 12:00
15:00 - 17:00
20:00 - 21:00

我已经想到了正则表达式替换和各种 for 循环,这些循环在我完成之前变得复杂......这并不是那么微妙:

string = string.replaceAll("- 01:00, 01:00", "");
string = string.replaceAll("- 02:00, 02:00", "");
string = string.replaceAll("- 03:00, 03:00", "");
etc

标签: regexdart

解决方案


ARegExp不理解文本的含义,只理解结构,因此您通常最好解析文本并使用能够理解正在发生的事情的代码来处理它。

在这种特殊情况下,您的文本结构实际上非常简单,aRegExp可以处理它,因为您正在寻找- xy:zw, xy:zw任何数字 x、y、z 和 w。

一个RegExp数学运算是:

var repeatedTimeRE = RegExp(r"- (\d\d:\d\d), \1 ");

然后,您可以替换 dostring = string.replaceAll(repatedTimeRE, "");以加入相邻的时间间隔,其中第二个开始的时间与第一个结束的时间完全相同。

如果您的格式与所写的不完全一致,例如可以将 1 点钟同时写为“1:00”和“01:00”,那么文本匹配就会变得更加困难。如果您可以有重叠的间隔,那么 aRegExp也无法捕捉到它,例如: 01:00 - 02:00, 01:59 - 02:35。语义合并功能无论如何都可以识别重叠和合并,文本匹配仅适用于严格相等的文本。


推荐阅读