【问题标题】:How to convert a List<String?> to List<String> in null safe Dart?如何在空安全 Dart 中将 List<String?> 转换为 List<String>?
【发布时间】:2021-06-27 23:41:53
【问题描述】:

我有一个飞镖列表:

List<String?> vals;

我想删除所有空值并将其转换为List&lt;String&gt;。 我试过了:

List<String> removeNulls(List<String?> list) {
  return list.where((c) => c != null).toList() as List<String>;
}

在运行时我收到以下错误:

List<String?>' is not a subtype of type 'List<String>?'

解决这个问题的正确方法是什么?

【问题讨论】:

  • collection,提供了一个扩展来做到这一点:whereNotNull()

标签: dart dart-null-safety


【解决方案1】:
  • 理想情况下,您首先应从List&lt;String&gt; 开始。如果您正在构建您的列表,例如:

    String? s = maybeNullString();
    var list = <String?>[
      'foo',
      'bar',
      someCondition ? 'baz' : null,
      s,
    ];
    

    那么您可以改为使用 collection-if 来避免插入 null 元素:

    String? s = maybeNullString();
    var list = <String?>[
      'foo',
      'bar',
      if (someCondition) 'baz',
      if (s != null) s,
    ];
    
  • Iterable&lt;T?&gt; 中过滤出null 值并获得Iterable&lt;T&gt; 结果的简单方法是使用.whereType&lt;T&gt;()。例如:

    var list = <String?>['foo', 'bar', null, 'baz', null];
    var withoutNulls = list.whereType<String>().toList();
    
  • 另一种方法是使用collection-for和collection-if

    var list = <String?>['foo', 'bar', null, 'baz', null];
    var withoutNulls = <String>[
      for (var s in list)
        if (s != null) s
    ];
    
  • 最后,如果您已经知道您的List 不包含任何null 元素,但只需要将元素转换为不可为空的类型,则其他选项是使用List.from

    var list = <String?>['foo', 'bar', null, 'baz', null];
    var withoutNulls = List<String>.from(list.where((c) => c != null));
    

    或者如果您不想创建新的ListIterable.cast

    var list = <String?>['foo', 'bar', null, 'baz', null];
    var withoutNulls = list.where((c) => c != null).cast<String>();
    

【讨论】:

  • 所以没有办法在不重新创建字符串的情况下进行转换。我的代码删除了空值,这是核心问题。
  • @BrettSutton 我忘记了Iterable.cast/List.cast,它不需要创建新的List。我已经更新了我的答案。
【解决方案2】:
  • 不创建新的List

    void main() {
      List<String?> list = ['a', null, 'b', 'c', null];
      list.removeWhere((e) => e == null); // <-- This is all you need.
      print(list); // [a, b, c]
    }
    
  • 创建一个新的List

    首先创建一个方法,例如filter

    List<String> filter(List<String?> input) {
      input.removeWhere((e) => e == null);
      return List<String>.from(input);
    }
    

    您现在可以使用它了:

    void main() {
      List<String?> list = ['a', null, 'b', 'c', null];
      List<String> filteredList = filter(list); // New list
      print(filteredList); // [a, b, c]
    }
    

要使用retainWhere,请将removeWhere 中的谓词替换为(e) =&gt; e != null

【讨论】:

  • 不创建新列表不符合要求,因为您最终不会得到 List。它可能不包含任何空项,但列表仍然是错误的类型。
  • @BrettSutton 如果你想从List&lt;String? 获得List&lt;String&gt;,你必须创建一个新列表,我的第二个代码就是这样做的。
猜你喜欢
  • 2013-08-26
  • 2020-01-11
  • 1970-01-01
  • 1970-01-01
  • 2022-01-05
  • 1970-01-01
  • 2021-09-17
  • 1970-01-01
  • 2019-09-10
相关资源
最近更新 更多