You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Dart List中补全索引区间

在Dart中生成包含目标区间和剩余部分的完整索引区间列表

我有一个Dart的int类型列表:

List<int> myList = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];

已知几个索引区间:

(5,9)
(13,16)

需要生成包含原区间和剩余部分的完整区间列表,最终结果如下:

(0,4)
(5,9)
(10,12)
(13,16)
(17,20)

背景是要根据这些区间对字符串的不同部分设置样式(比如给目标区间设置粗体),尝试过removeRange(删除后索引错位无法继续操作)、sublist和splitBetween但都没达到预期,该如何实现?


实现思路

不要直接修改原列表(会导致索引偏移),而是基于原列表的固定范围,先对已知目标区间排序,再逐个计算相邻区间之间的空白部分,最后将空白区间与目标区间合并成完整序列。

代码实现

  1. 先定义一个简单的Range类来存储区间的起始和结束索引:
class Range {
  final int start;
  final int end;

  Range(this.start, this.end);

  @override
  String toString() => '($start,$end)';
}
  1. 编写生成完整区间列表的函数:
List<Range> generateFullRanges(List<Range> targetRanges, int totalLength) {
  final fullRanges = <Range>[];
  int currentStart = 0;
  // 先对目标区间按起始索引升序排序,确保顺序正确
  final sortedRanges = [...targetRanges]..sort((a, b) => a.start.compareTo(b.start));

  for (final range in sortedRanges) {
    // 添加当前目标区间之前的空白区间
    if (currentStart < range.start) {
      fullRanges.add(Range(currentStart, range.start - 1));
    }
    // 添加目标区间
    fullRanges.add(range);
    // 更新当前起始位置为目标区间的下一个索引
    currentStart = range.end + 1;
  }

  // 添加最后一个目标区间之后的空白区间
  if (currentStart <= totalLength - 1) {
    fullRanges.add(Range(currentStart, totalLength - 1));
  }

  return fullRanges;
}
  1. 使用示例:
void main() {
  List<int> myList = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
  List<Range> targetRanges = [Range(5,9), Range(13,16)];

  var fullRanges = generateFullRanges(targetRanges, myList.length);
  for (var r in fullRanges) {
    print(r);
  }
}

运行后输出:

(0,4)
(5,9)
(10,12)
(13,16)
(17,20)

针对字符串样式的扩展使用

如果是用于字符串分段设置样式,可以直接用生成的区间截取字符串片段,再分别处理样式:

void applyTextStyles(String text, List<Range> targetRanges) {
  var fullRanges = generateFullRanges(targetRanges, text.length);

  for (var range in fullRanges) {
    String segment = text.substring(range.start, range.end + 1); // Dart的substring是左闭右开,所以end要+1
    // 判断当前区间是否是需要特殊样式的目标区间
    bool isTarget = targetRanges.any((tr) => tr.start == range.start && tr.end == range.end);
    if (isTarget) {
      // 示例:用Markdown粗体标记,实际场景可替换为Flutter的TextStyle等
      print("**$segment**");
    } else {
      print(segment);
    }
  }
}

// 使用示例
void main() {
  String text = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  List<Range> targetRanges = [Range(5,9), Range(13,16)];
  applyTextStyles(text, targetRanges);
}

内容的提问来源于stack exchange,提问作者Clifton Labrum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 19:31:24