如何组合嵌套列表中的所有字符串?

时间:2014-02-16 13:07:14

标签: list dart fold

我有一个列表,其中包含多级嵌套列表。每个列表都可以包含字符串和其他类型实例。

E.g。

var list = [ 'a', 'w', ['e', ['f', new Object(), 'f'], 'g'], 't', 'e'];

我想编写一个函数(比如compress)来将字符串与其兄弟节点组合在一起,并保持其他类型实例不变,最后得到一个没有嵌套列表的列表。

compress(list){       // 如何 ?    }

compress(list)的结果将是:

['awef', new Object(), 'fgte']

它是否是快速而明确的解决方案?

5 个答案:

答案 0 :(得分:5)

Terse和功能性FTW

List compress(Iterable iterable) => concat(flatten(iterable));

Iterable flatten(Iterable iterable) => 
    iterable.expand((e) => e is Iterable ? flatten(e) : [e]);

List concat(Iterable iterable) => iterable.fold([], (list, e) => 
    list..add((e is String && list.isNotEmpty && list.last is String)
        ? list.removeLast() + e : e));

答案 1 :(得分:2)

这包括两个问题,一个非常标准的问题(展平列表),然后充分加入字符串。

flatten(Iterable l) => l.fold([], (List list, element) {
  if (element is Iterable)
    list.addAll(flatten(element));
  else
    list.add(element);
  return list;
});

concat(Iterable l) => l.fold([], (List list, element) {
  if (element is String && !list.isEmpty && list.last is String)
    list.add(list.removeLast() + element);
  else
    list.add(element);
  return list;
});

void main() {
  var nested = [ 'a', 'w', ['e', ['f', new Object(), 'f'], 'g'], 't', 'e'];
  print(concat(flatten(nested));
}

更新

一种变形的concat,灵感来自Greg Lowe(完全像我的“大”和他的那个,但更加浓缩):

concat(Iterable list) => list.fold([], (List xs, x) => xs..add(
    x is String && !xs.isEmpty && xs.last is String ? xs.removeLast() + x : x));

你可以根据需要结合他和我的功能,他们做的完全相同。

答案 2 :(得分:2)

如果您有很多字符串,可能需要使用StringBuffer进行连接。 我的猜测是,在大多数情况下,这不是问题。

List compress(List list) {
  var sb = new StringBuffer();
  List result = [];
  List compressRec(List list) {
    for (var element in list) {
      if (element is String) {
        sb.write(element);
      } else if (element is List) {
          compressRec(list);
      } else {
        if (sb.isNotEmpty()) {
          result.add(sb.toString());
          sb.clear();
        }
        result.add(element);
      }
    }
  }
  compressRec(list)
  if (sb.isNotEmpty()) {
    result.add(sb.toString());
  }
  return result;
}

答案 3 :(得分:1)

这是我的猜测:

compress(List l, [List p]) => l.fold(p != null ? p : [], (List t, e) {
  if (e is String) {
    if (t.isEmpty || t.last is! String) t.add(e);
    else t.add(t.removeLast() + e);
  } else if (e is List) compress(e, t);
  else t.add(e);
  return t;
});

答案 4 :(得分:0)

我的尝试

List flatten(List l) {
  List result = [''];
  int cur = 0;

  var add = (f) {
    if(f is String) {
      result[cur] += f;
    } else {
      result.add(f);
      result.add('');
      cur += 2;
    }
  };

  l.forEach((e) {
    if(e is List) {
      flatten(e).forEach((e) => add(e));
    } else {
      add(e);
    }
  });
  return result;
}