How to combine all the lines in a nested list?

I have a list that contains multi-level nested lists. Each list may contain strings and other type instances.

eg.

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

I want to write a function (say compress) to merge strings with my siblings, as well as leave other instances of the type intact and finally get a list that doesn't have a nested list.

compress (list) {// how? }

And the result compress(list)will be:

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

Is this a quick and clear solution?

+4
source share
5 answers

Close and functional 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));
+4
source

, ( ) .

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));
}

Update:

concat, ( , "" , ):

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

, .

+2

You might want to use StringBuffer to concatenate if you have many strings. I assume that in most cases this is not a problem.

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;
}
+2
source

Here is my hunch:

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;
});
+1
source

My attempt

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;
}
0
source

Source: https://habr.com/ru/post/1527179/


All Articles