我试图从包含来自单独字符串列表的任何元素的字符串列表中排除元素,以从第一个列表中生成剩余字符串的第三个列表。
var original_list = ['cigar', 'rebut', 'focal', 'blush', 'naval', 'bench'];
var exclusion_list = ['e', 'f'];
var result_list = [];
我还在熟悉Dart语法。在Python中,我会做类似的事情:
for item in original_list:
if not any(letter in original_list for letter in exclusion_list):
result_list.append(item)
我一直在兜圈子,试图找到一个优雅的解决方案,但我总是回到一些丑陋的嵌套for循环。
任何帮助将不胜感激!
我已经着陆了
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]);
}
}
不是最优雅的,但它会"过滤"列出list1中包含list2中字符的字符串。
暴力执行将是:
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);
}
这基本上就是你所拥有的,但是使用一个标签来继续外部循环,而不是一个标志来避免在里面做更多的工作。
内环可以用any
代替,变成:
if (exception.any(value.contains)) {
continue outer;
}
result.add(value);
它使用Iterable.any
方法来检查disallowedSubstrings
的每个元素,并使用一个方法撕下来做传递一个函数,有效地执行(x) => value.contains(x)
。
但是我们有一个if
,最好写它来保护循环体的其余部分,而不是继续:
if (!disallowedSubstrings.any(value.contains)) {
result.add(value);
}
剩下for
和if
执行add
,我们可以将其转换为列表字面量:
var result = [for (var value in source)
if (!disallowedSubstrings.any(value.contains)) value
];
这更接近Python版本。
或者,如果不使用列表文字,也可以写成:
var result = source.where((value) =>
!disallowedSubstrings.any(value.contains)
).toList();