【问题标题】:How to set length of list in dart with default value?如何使用默认值设置飞镖列表的长度?
【发布时间】:2021-06-09 15:07:33
【问题描述】:

在我的应用程序中,我在很多地方都使用过这样的列表:-

List<int> nums = [];
// initializing list dynamically with some values.
nums.length = 12; // increasing length of list
// setting these values afterward using nums[i] at different places.

现在迁移到空安全后,显然nums.length = 4 给了我一个运行时错误,所以我想知道是否有任何方法可以使用默认值设置列表的长度,这样,如果列表的长度是比以前更小,添加了新长度的额外元素,并添加了一些默认值。

注意:我当然知道我们可以使用 for 循环,但我只是想知道是否有比这更简单、更简洁的方法。

【问题讨论】:

  • 你想用什么来填充列表?什么决定了这个默认值?
  • @julemand101 我希望列表填充 0 或任何值,因为在使用它之前我将最终分配它,我只需要在增加它的同时临时为其分配一些值而不是 null长度。

标签: list flutter dart


【解决方案1】:

另一种方法:

extension ExtendList<T> on List<T> {
  void extend(int newLength, T defaultValue) {
    assert(newLength >= 0);

    final lengthDifference = newLength - this.length;
    if (lengthDifference <= 0) {
      return;
    }

    this.addAll(List.filled(lengthDifference, defaultValue));
  }
}

void main() {
  var list = <int>[];
  list.extend(4, 0);
  print(list); // [0, 0, 0, 0];
}

或者,如果您必须设置.length 而不是调用单独的方法,您可以将其与julemand101's answer 的变体结合使用指定的默认值而不是null

class ExtendableList<T> with ListMixin<T> {
  ExtendableList(this.defaultValue);

  final T defaultValue;
  final List<T> _list = [];

  @override
  int get length => _list.length;

  @override
  T operator [](int index) => _list[index];

  @override
  void operator []=(int index, T value) {
    if (index >= length) {
      _list.extend(index + 1, defaultValue);
    }
    _list[index] = value;
  }

  @override
  set length(int newLength) {
    if (newLength > length) {
      _list.extend(newLength, defaultValue);
    } else {
      _list.length = newLength;
    }
  }
}

(我也让它的operator []=自动增长ExtendableList如果指定的索引超出范围,类似于JavaScript。)

【讨论】:

    【解决方案2】:
    var num = List<int>.generate(4, (i) => i);
    

    您可以阅读this

    【讨论】:

    • 这不起作用,因为这将替换nums 的所有值我想用默认值增加长度。
    • 如果你想增加它,那么你可以这样做num.addAll([1,1,1,1,1,1,1])num.addAll(List&lt;int&gt;.generate(20, (i) =&gt; 0))
    【解决方案3】:

    您的问题是 Dart 中的 List 没有添加更多空间的概念,而您承诺在设置之前不会使用此新容量。

    但是您可以轻松地制作自己的 List 实现,它可以做到这一点:

    import 'dart:collection';
    
    void main() {
      List<int> nums = ExtendableList();
      nums.length = 3;
    
      nums[2] = 1;
      nums[0] = 1;
      nums[1] = 1;
    
      print(nums); // [1, 1, 1]
      nums.add(2);
      print(nums); // [1, 1, 1, 2]
      print(nums.runtimeType); // ExtendableList<int>
    }
    
    class ExtendableList<T> with ListMixin<T> {
      final List<T?> _list = [];
    
      @override
      int get length => _list.length;
    
      @override
      T operator [](int index) => _list[index] as T;
    
      @override
      void operator []=(int index, T value) => _list[index] = value;
    
      @override
      set length(int newLength) => _list.length = newLength;
    }
    

    如您所见,我们在后台使用了 null 类型,但从外部看,它会像列表包含不可为空的一样工作。这只是因为我们假设null 值在列表中时不会调用[] 运算符(如果我们扩展列表但未设置值,则会发生这种情况)。

    我应该补充一点,使用这样的List 实现确实会带来很大的风险,因为如果您使用不当,分析器不会收到任何警告/错误。

    【讨论】:

    • 另一种方法是创建一个List 类型,其中包含一个默认值,每次需要扩展时都应该使用它来填充列表。
    【解决方案4】:

    你必须使用一个可以为空的元素列表来让它更长。

    List<int?> nums = [];
    nums.length = 4; // OK
    print(nums); // [null, null, null, null]
    

    【讨论】:

    • 好吧,我需要一个不可为空的列表,如果可以的话,我会更喜欢这样的东西 List&lt;late int&gt; nums = [];
    【解决方案5】:

    您也可以使用filled 方法。这里growable默认为false

    void main() {
      var a = List<int>.filled(3, 0, growable: true);
      print(a);
      // [0, 0, 0]
    }
    

    参考:https://api.flutter.dev/flutter/dart-core/List/List.filled.html

    【讨论】:

    • 好吧,我试过这样的方法,但问题是当我将长度增加a.length = 5 \\ or something 时,它仍然会用null 填充新元素。
    猜你喜欢
    • 2021-09-14
    • 2023-03-16
    • 2016-07-05
    • 2021-12-20
    • 2021-10-12
    • 2022-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多