Skip to content

Support generics #2

Description

@ivanmem

I would like to see generic support added to the library. Here is an example implementation:

class ClonerService {
  static List<T> deepcopyList<T>(List<T> list) {
    List<T> copy = [];
    for (final item in list) {
      if (item is Map) {
        copy.add(deepcopyMap(item) as T);
      } else if (item is List) {
        copy.add(deepcopyList(item) as T);
      } else if (item is Set) {
        copy.add(deepcopySet(item) as T);
      } else {
        copy.add(item);
      }
    }
    return copy;
  }

  static Map<TKey, TValue> deepcopyMap<TKey, TValue>(Map<TKey, TValue> map) {
    Map<TKey, TValue> copy = {};
    for (final entry in map.entries) {
      final key = entry.key;
      final value = entry.value;

      if (value is Map) {
        copy[key] = deepcopyMap(value) as TValue;
      } else if (value is List) {
        copy[key] = deepcopyList(value) as TValue;
      } else if (value is Set) {
        copy[key] = deepcopySet(value) as TValue;
      } else {
        copy[key] = value;
      }
    }
    return copy;
  }

  static Set<T> deepcopySet<T>(Set<T> set) {
    Set<T> copy = {};
    for (final item in set) {
      if (item is Map) {
        copy.add(deepcopyMap(item) as T);
      } else if (item is List) {
        copy.add(deepcopyList(item) as T);
      } else if (item is Set) {
        copy.add(deepcopySet(item) as T);
      } else {
        copy.add(item);
      }
    }
    return copy;
  }
}


extension MapExtensions<TKey, TValue> on Map<TKey, TValue> {
  Map<TKey, TValue> deepcopy() {
    return ClonerService.deepcopyMap<TKey, TValue>(this);
  }
}

extension ListExtensions<TKey, T> on List<T> {
  List<T> deepcopy() {
    return ClonerService.deepcopyList<T>(this);
  }
}

extension SetExtensions<T> on Set<T> {
  Set<T> deepcopy() {
    return ClonerService.deepcopySet<T>(this);
  }
}

Tests:

void main() {
  group('cloner', () {
    testWidgets('Map<int, Map>', (tester) async {
      final Map<int, Map> original = {
        1: {
          'abc': {'abc': 'abc'}
        }
      };
      final copy = original.deepcopy();
      expect(original.values.first.entries.first != copy.values.first.entries.first,
          true);
    });

    testWidgets('List<Map>', (tester) async {
      final List<Map> original = [
        {
          'abc': {'abc': 'abc'}
        }
      ];
      final copy = original.deepcopy();
      expect(original.first.entries.first != copy.first.entries.first, true);
    });

    testWidgets('Set<Map>', (tester) async {
      final Set<Map> original = {
        {
          'abc': {'abc': 'abc'}
        }
      };
      final copy = original.deepcopy();
      expect(original.first.entries.first != copy.first.entries.first, true);
    });
  });
}

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions