【问题标题】:List firstWhere Bad state: No elementList firstWhere 坏状态:无元素
【发布时间】:2019-02-20 13:53:22
【问题描述】:

我正在运行 list.firstWhere,这有时会引发异常:

Bad State: No element

When the exception was thrown, this was the stack:
#0      _ListBase&Object&ListMixin.firstWhere (dart:collection/list.dart:148:5)

我不明白这意味着什么,也无法通过查看 at the source 来识别问题。

我的firstWhere 看起来像这样:

list.firstWhere((element) => a == b);

【问题讨论】:

    标签: dart


    【解决方案1】:

    当没有匹配的元素时会发生这种情况,即当a == blist 中的任何元素都不为真时 可选参数orElse 未指定。

    您也可以指定orElse来处理这种情况:

    list.firstWhere((a) => a == b, orElse: () => print('No matching element.'));
    

    如果您想在不匹配时返回null,也可以使用orElse

    list.firstWhere((a) => a == b, orElse: () => null);
    

    package:collection 还包含null 案例的便利扩展方法(它也应该更好地用于空安全):

    import 'package:collection/collection.dart';
    
    list.firstWhereOrNull((element) => element == other);
    

    请参阅firstWhereOrNull 了解更多信息。感谢@EdwinLiu 指出。

    【讨论】:

    • list.firstWhere((element) => a == b, orElse: () => null); 允许您静默返回 null。
    • 这些奇怪的 Flutter 开发者本可以通过这种方式返回 null。
    • @AbdulSaleem 你不是说 Dart 开发者吗?)
    • NULL SAFETY 的解决方案是什么?请分享。谢谢
    • @Kamlesh for null 安全是答案中所述:firstWhereOrNull using collection package
    【解决方案2】:

    firstWhere返回根据条件生成的newList

    void main() {
      List<String> list = ['red', 'yellow', 'pink', 'blue'];
      var newList = list.firstWhere((element) => element == 'green', 
          orElse: () => 'No matching color found');
      print(newList);
    }
    

    输出:

    No matching color found
    

     void main() {
          List<String> list = ['red', 'yellow', 'pink', 'blue'];
          var newList = list.firstWhere((element) => element == 'blue', 
              orElse: () => 'No matching color found');
          print(newList);
        }
    

    输出:

    blue
    

    如果代码中没有定义 orElse 并且错误的项目被搜索到列表中不存在,那么它会显示 BadStateException

     void main() {
          List<String> list = ['red', 'yellow', 'pink', 'blue'];
          var newList = list.firstWhere((element) => element == 'green');
          print(newList);
        }
    

    输出:

    Uncaught Error: Bad state: No element
    

    【讨论】:

    • 同样的问题..帮助..stackoverflow.com/questions/64154373/…
    • 虽然我完全同意这个答案,但我只想指出一个逻辑错误。如果您将“绿黄色”添加为列表项,则条件 1 和 3 将不会打印上述输出。 element == 'green' 将是合适的条件。但对答案表示敬意
    • @SKT:感谢您的建议更正
    【解决方案3】:

    现在你可以导入package:collection并使用扩展方法firstWhereOrNull

    import 'package:collection/collection.dart';
    
    void main() {
    
      final myList = [1, 2, 3];
    
      final myElement = myList.firstWhereOrNull((a) => a == 4);
    
      print(myElement); // null
    }
    

    【讨论】:

      【解决方案4】:

      firstWhere() 实现如下所示:

        E firstWhere(bool test(E element), {E orElse()?}) {
          for (E element in this) {
            if (test(element)) return element;
          }
          if (orElse != null) return orElse();
          throw IterableElementError.noElement();
        }
      

      如您所见,如果定义了 orElse 参数,则该方法将使用该参数,并且如果没有任何元素符合条件,则不会抛出任何异常。所以使用下面的代码来处理错误的情况:

      list.firstWhere((element) => a == b, orElse: () => null); // To return null if no elements match
      list.firstWhere((element) => a == b, orElse: () => print('No elements matched the condition'));
      

      【讨论】:

        【解决方案5】:

        在 dart 2.10 上有一个名为 null-safety 的新功能,当你有一个对象列表并且你想对一个特定对象的属性做某事时,它可以为你变魔术:

        class User {
           String name;
           int age;
        
          User(this.name, this.age);
        
           @override
           String toString() {
           return  'name:$name, age:$age';
           }
        
        }
        
        void main() {
          List<User?> users = [User("Ali", 20), User("Mammad", 40)];
          print(users.toString()); // -> [name:Ali, age:20, name:Mammad, age:40]
          // modify user age who it's name is Ali:
          users.firstWhere((element) => element?.name == "Ali")?.age = 30;
          print(users.toString()); // -> [name:Ali, age:30, name:Mammad, age:40]
          // modify a user that doesn't exist:
          users.firstWhere((element) => element?.name == "AliReza", orElse: ()=> null)?.age = 30; // doesn't find and works fine
          print(users.toString()); // -> [name:Ali, age:30, name:Mammad, age:40]
        
        }
        
        

        【讨论】:

          猜你喜欢
          • 2022-07-01
          • 2021-12-20
          • 2022-11-27
          • 1970-01-01
          • 2020-10-08
          • 1970-01-01
          • 1970-01-01
          • 2021-08-11
          • 2019-12-21
          相关资源
          最近更新 更多