Home > database >  Excluding strings from list of strings that contain substrings from separate list of substrings
Excluding strings from list of strings that contain substrings from separate list of substrings

Time:12-30

I am trying to exclude elements from a list of strings that contain any element from a separate list of strings to produce a third list of remaining strings from the first list.

var original_list = ['cigar', 'rebut', 'focal', 'blush', 'naval', 'bench'];
var exclusion_list = ['e', 'f'];
var result_list = [];

I'm still getting familiar with Dart syntax. In Python, I would have done something similar to:

for item in original_list:
    if not any(letter in original_list for letter in exclusion_list):
        result_list.append(item)

I've been going round and round in dartpad trying to come up with an elegant solution but I keep coming back to some ugly nested for loops.

Any help would be appreciated!

CodePudding user response:

I've landed on this


      var list1 = ['cigar', 'rebut', 'focal', 'blush', 'naval', 'bench'];
      var list2 = ['e', 'f'];
      var remaining = [];
      int flag;
      
      for(int i = 0;i < list1.length;i  ) {
        flag = 0;
        for(int j = 0; j < list2.length;j  ) {
          if(list1[i].contains(list2[j])) {
            flag = 1;
            continue;
          }
        }
        if(flag==0) {
          remaining.add(list1[i]);
        }
      }

Not the most elegant but it will "filter" out the strings in list1 that contain the characters in list2.

CodePudding user response:

The brutes-force implementation would be:

List<String> source = ...;
List<String> disallowedSubstrings = ...;
// ...
var result = <String>[];
outer:
for (var value in source) {
  for (var exception in disallowedSubstrings) {
    if (value.contains(exception)) {
      continue outer;
    }
  }
  result.add(value);
}

That's basically what you have, but using a label to continue the outer loop, instead of a flag to avoid doing more work inside it.

The inner loop can be replaced using any, becoming:

if (exception.any(value.contains)) {
  continue outer;
}
result.add(value);

It uses the Iterable.any method to check something for every element of disallowedSubstrings, and a method tear-off to do pass in a function which effectively does (x) => value.contains(x).

But then we have an if, and might as well write it to guard the rest of the loop body, instead of continuing:

  if (!disallowedSubstrings.any(value.contains)) {
    result.add(value);
  }

That leaves us with a for and an if doing an add, which we can turn into a list literal:

var result = [for (var value in source) 
  if (!disallowedSubstrings.any(value.contains)) value
];

That's much closer to the Python version.

Alternatively, if not using a list literal, it can also be written as:

var result = source.where((value) => 
    !disallowedSubstrings.any(value.contains)
).toList();
  •  Tags:  
  • dart
  • Related