0

I've two lists of objects that i wanna compare, a and b:

final dia = DateTime(2017, 9, 7, 17, 30);
final ppp = Parcela("1", 225.5, dia, null, 1, false, false);
final ppp2 =Parcela("1", 225, dia.add(const Duration(days: 3)), null, 1, false, false);
final ppp3 =Parcela("1", 225, dia.add(const Duration(days: 3)), null, 1, false, false);
List<Parcela> a = [ppp,ppp2,];
List<Parcela> b = [ppp, ppp3];

Both of them are equal, but when i try to check it with the functions bellow i get false on response:

print(a.every(b.toSet().contains));
print(listEquals(a, b));

I tried also "quiver" and "collection" libraries from pub dev but the result is the same

The Parcela model:

class Parcela {
  String id;
  double valor;
  DateTime dataPagamento;
  DateTime dataPago;
  int status;
  int ref;

  Parcela(String id, double valor, DateTime dataPagamento, DateTime dataPago,
      int ref, bool pago, bool atraso) {
    this.id = id;
    this.valor = valor;
    this.dataPagamento = dataPagamento;
    this.dataPago = this.dataPago;
    this.status = _getStatus(pago, atraso);
    this.ref = this.ref;
  }
  int _getStatus(bool pago, bool atraso) {
    if (pago) {
      if (atraso) {
        return 3;
      } else {
        return 1;
      }
    } else {
      if (atraso) {
        return 2;
      } else {
        return 0;
      }
    }
  }
}

Edit1:

I've tried Dan James suggestion but my class isn't final as his, so i've removed "final" from name attribute:

class Person extends Equatable {
   Person(this.name);

   String name;

  @override
  List<Object> get props => [name];

}

the new test vars:

Person p = Person("name");
Person p2 = Person("name2");
Person p3 = Person("tobias");

List<Person> aa = [p, p2];
List<Person> bb = [p, p2..name = "teste"];
List<Person> cc = [p, p3];

but when i test the lists:

var filtered_lst =List.from(aa.where((value) => !bb.contains(value)));
print(filtered_lst);
print(listEquals(aa, bb));
print(listEquals(aa, cc));

the console returns this:

I/flutter (12746): []
I/flutter (12746): true
I/flutter (12746): false

2 Answers 2

2

ppp2 does not equal ppp3 because they are two different instances of a class. You could override the '==' operator to check if each field is the same. ie. ppp2.id == ppp3.id.

eg/ (taken from equatable docs but this is vanillar dart)

class Person {
  const Person(this.name);

  final String name;

  @override
  bool operator ==(Object other) =>
    identical(this, other) ||
    other is Person &&
    runtimeType == other.runtimeType &&
    name == other.name;

  @override
  int get hashCode => name.hashCode;
}

Or look into the equatable package which does this for you. https://pub.dev/packages/equatable

Straight from the equatable docs:

import 'package:equatable/equatable.dart';

class Person extends Equatable {
  const Person(this.name);

  final String name;

  @override
  List<Object> get props => [name];

}
Sign up to request clarification or add additional context in comments.

6 Comments

can you add a sample code to your answer?
your solution doesn't work: Person p = Person("name"); Person p2 = Person("name2"); List<Person> aa = [p, p2]; List<Person> bb = [p, p2..name = "teste"]; print(listEquals(aa, bb)); returns true
It's returning true in the first comparison because when you do p2..name = "teste" you're also modifying the p2 object inside aa, so aa and bb will be true.
Is there any way of generating a copy of another list that doesn't point to the same address of memory?
using the spread operator is an easy way to create a new list. eg/. List list2 = [...list1];
|
0

Using the library equatable from Dan James answer:

import 'package:equatable/equatable.dart';

// ignore: must_be_immutable
class Parcela extends Equatable {
  String id;
  double valor;
  DateTime dataPagamento;
  DateTime dataPago;
  int status;
  int ref;

  Parcela(String id, double valor, DateTime dataPagamento, DateTime dataPago,
      int ref, bool pago, bool atraso) {
    this.id = id;
    this.valor = valor;
    this.dataPagamento = dataPagamento;
    this.dataPago = this.dataPago;
    this.status = _getStatus(pago, atraso);
    this.ref = this.ref;
  }
  int _getStatus(bool pago, bool atraso) {
    if (pago) {
      if (atraso) {
        return 3;
      } else {
        return 2;
      }
    } else {
      if (atraso) {
        return 1;
      } else {
        return 0;
      }
    }
  }
  @override
  List<Object> get props => [id,valor,dataPagamento,];
}

The only way of copying a list that doesn't point to the same memory address:

List<Parcela> copyParcelas(List<Parcela> list) {
  List<Parcela> copyList = [];
  for (var item in list) {
    List<bool> _status = pagoAtraso(item.status);
    Parcela betItems = Parcela(item.id, item.valor, item.dataPagamento,
        item.dataPago, item.ref, _status[0], _status[1]);
    copyList.add(betItems);
  }
  return copyList;
}

Then the check to return the list items that changed:

List<Parcela> editarParcelas(List<Parcela> parcelas, List<Parcela> original){
    return filteredlst = parcelas.toSet().difference(original.toSet()).toList();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.