Home > OS >  Dart - How to merge two list of objects into singe list
Dart - How to merge two list of objects into singe list

Time:06-20

2> as you can see below i have two list of object and i want to merge into single it should compare list based on date

//here is the list 1
List<Object1> list1=[
Object1("date":"1","day_data":12),
Object1("date":"2","day_data":15),
]

//here is the list 2
List<Object2> list2=[
Object2("date":"1","night_data":56),
Object2("date":"3","night_data":80),
];

//expected output
List<Object3> expectedList=[
Object3("date":"1","day_data":12,"night_data":56),
Object3("date":"2","day_data":15,"night_data":null),
Object3("date":"3","day_data":null,"night_data":80),
];

CodePudding user response:

The code below should do the trick. It uses a Map where the keys are, let's say, the Primary Key. And the values are the reduce from list1 and list2 (It even merges duplicated items by date from list1 and/or list2). At the end, I've added some asserts to actually test if it works.

Here's also the DartPad to run it online.

class Object1 {
  final String date;
  final int day_data;
  const Object1({required this.date, required this.day_data});
}

class Object2 {
  final String date;
  final int night_data;
  const Object2({required this.date, required this.night_data});
}

class Object3 {
  final String date;
  final int? day_data;
  final int? night_data;
  const Object3({required this.date, this.day_data, this.night_data});
}

List<Object3> merge(List<Object1> obj1List, List<Object2> obj2List) {
  final map = <String, Object3>{};
  obj1List.forEach((obj1) =>
      map.update(
        obj1.date, 
        (obj3) => Object3(date: obj3.date, day_data: obj1.day_data, night_data: obj3.night_data),
        ifAbsent: () => Object3(date: obj1.date, day_data: obj1.day_data, night_data: null),
      ));
  
  obj2List.forEach((obj2) =>
      map.update(
        obj2.date, 
        (obj3) => Object3(date: obj3.date, day_data: obj3.day_data, night_data: obj2.night_data),
        ifAbsent: () => Object3(date: obj2.date, day_data: null, night_data: obj2.night_data),
      ));
  
  return map.values.toList()
    ..sort((a, b) => a.date.compareTo(b.date));
}


void main() {
//here is the list 1
  List<Object1> list1=[
  Object1(date:"1",day_data:12),
  Object1(date:"2",day_data:15),
  ];

  //here is the list 2
  List<Object2> list2=[
  Object2(date:"1",night_data:56),
  Object2(date:"3",night_data:80),
  ];

  List<Object3> actualList = merge(list1, list2);
  
  //expected output
  List<Object3> expectedList=[
  Object3(date:"1",day_data:12,night_data:56),
  Object3(date:"2",day_data:15,night_data:null),
  Object3(date:"3",day_data:null,night_data:80),
  ];
  
  print('Checking size...');  
  assert(actualList.length == expectedList.length);
  print('OK');
  
  print('Checking items...');
  actualList.asMap().forEach((i, actual) {
    final expected = expectedList[i];
    print('  Checking item $i...');
    assert(actual.date == expected.date);
    assert(actual.day_data == expected.day_data);
    assert(actual.night_data == expected.night_data);
    print('  OK');
  });
  print('OK');
}

CodePudding user response:

You need to do manually with two loops and comparing dates.

CodePudding user response:

Hey you can achieve by compering two list and get list like below -

   void compareList(){
    List<ObjectModel> list1=[
      ObjectModel(date:"1",dayData:12),
      ObjectModel(date:"2",dayData:15),
    ];

   //here is the list 2
    List<ObjectModel> list2=[
      ObjectModel(date:"1",nightData:56),
      ObjectModel(date:"3",nightData:80),
    ];

   //expected output
    List<ObjectModel> expectedList= [];

    list1.forEach((element) {
      ObjectModel innerObject = list2.firstWhere((ObjectModel innerElement) => element.date == innerElement.date, orElse: (){return ObjectModel();});
      if(innerObject.date !=null){
        expectedList.add(ObjectModel(date:element.date,dayData:element.dayData,nightData: innerObject.nightData));
      }else{
        expectedList.add(element);
      }
    });

    list2.forEach((element) {
      ObjectModel innerObject = list1.firstWhere((ObjectModel innerElement) => element.date == innerElement.date, orElse: (){return ObjectModel();});
      if(innerObject.date ==null){
        expectedList.add(element);
      }
    });
    print(expectedList.length);
  }
    
    class ObjectModel{
      String? date;
      int? dayData;
      int? nightData;
    
      ObjectModel({ this.date, this.dayData, this.nightData});
    }
  • Related