dardo: ¿No existe una forma sencilla de hacer una lista profunda en Flutter?

CorePress2024-01-24  7

Probé List.from y [...orginalObject], pero tampoco una copia profunda. En ambos casos claramente se trata de copiar las referencias. Lo que significa que si cambio algún dato en la lista en la que copié los datos, los datos originales también cambian.

Me parece que la única forma de hacer un bucle for y definir cada una de las entradas es la lista copiada con un nuevo operador y los datos de cada una de las entradas correspondientes de la lista original. Algo como se muestra en la siguiente imagen.

Parece un enfoque bastante tedioso. ¿Existe algún método más sencillo?

Gracias.



------------------------------------

En vainilla Dart,En realidad no, ya que esto requeriría la capacidad de copiar los objetos hoja, y no hay forma de que el lenguaje sepa cómo hacerlo para objetos arbitrarios.

Sin embargo, los paquetes build_value y build_collection pueden resolver su problema. Una de sus principales características es la profunda inmutabilidad. Primero, escribes tus clases así:

class Item {
    final String foo;
    final int bar;
    
    Item(this.foo, this.bar);
}

// becomes

part 'item.g.dart';

abstract class Item extends Built<Item, ItemBuilder> {
    Item._();
    factory Item([void Function(ItemBuilder) updates]) = _$Item;
    // boilerplate, can use tooling to auto-generate

    String get foo;
    int get bar;
}

Esto le permite crear un objeto inmutable usando un constructor mutable y luego finalizarlo, por ejemplo:

final item1 = Item((b) {
    // here b is an ItemBuilder, the mutable version of Item
    b.foo = 'Hello';
    b.bar = 123;
});

final item2 = item1.rebuild((b) => b.foo = 'New Value');  // Item(foo: 'New Value', bar: 123)

Luego puedes usar build_collection para trabajar con colecciones profundamente inmutables de valores construidos, por ejemplo:

final list = BuiltList<Item>([item1, item2, item3]);

final deepCopy = list.rebuild((b) {});  // rebuild with no changes

final withNewElement = list.rebuild((b) => b.add(item4));

Lo importante de todos estos es que son inmutables y son "objetos de valor", lo que significa (entre otras cosas) que se consideran iguales si todos sus valores correspondientes son iguales. Puedes considerar eaLa llamada de reconstrucción de ch le devolverá una lista nueva con todos los valores copiados.

De hecho, la biblioteca es lo suficientemente inteligente como para crear solo nuevos objetos para los valores que realmente han cambiado, pero como es inmutable, actúa como una copia profunda, sin los posibles costos de rendimiento.

La principal desventaja de estas bibliotecas es que dependen de la generación de código, por lo que requieren un poco más de configuración que simplemente colocarlas en sus dependencias. A cambio, obtienes muchas características útiles además de tener objetos profundamente inmutables (como serialización json, verificación de nulos en código de seguridad previo a nulos, @memoized para almacenar en caché los resultados de cálculos costosos, etc.)



------------------------------------

Dart no tiene constructores de copia ni requiere métodos clone() en los objetos, por lo que no hay forma de copiar un objeto arbitrario y, por lo tanto, no hay forma de hacer una copia profunda de una colección de objetos arbitrarios.

La respuesta de Cameron1024 que sugiere el uso de package:built_value y package:built_collection es buena. Sin embargo, si no son adecuados para usted, puede crear una función que copie elementos mediante una devolución de llamada:

List<T> copyList<T>(Iterable<T> items, T Function(T element) copier) {
  return [
    for (var item in items) copier(item),
  ];
}

class Foo {
  int i;
  String s;
  
  Foo(this.i, this.s);
  
  @override
  String toString() => 'Foo($i, "$s")';
}

void main() {
  var list = [Foo(1, 'one'), Foo(2, 'two'), Foo(3, 'three')];
  print('Original: $list');
  
  var copy = copyList<Foo>(list, (foo) => Foo(foo.i, foo.s));

  list[0].i = 100;
  print('Mutated:  $list');
  print('Copy:     $copy');
}

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare