Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add deep copy for List and Map #159

Closed
wants to merge 1 commit into from

Conversation

myConsciousness
Copy link

Hi amazing developers,

I added utilities for deep copying of List and Map :)

@myConsciousness
Copy link
Author

cc @passsy @leisim

@passsy
Copy link
Collaborator

passsy commented Apr 26, 2022

That's not a deep copy. It is a normal copy like the official toList()

Here's the proof

    test('deep copy', () {
      final list = [1, 2, [3, 4]];
      final clone = list.clone();

      expect(clone, [1, 2, [3, 4]);
      expect(clone == list, false);

      // add item to original
      (list[2] as List).add(5);
      expect(list, [1, 2, [3, 4, 5]);

      // both fail because sub collections are copied by reference, not cloned
      expect(clone, [1, 2, [3, 4]);
      expect(identical(list[2], clone[2]]), isFalse);
    });

@myConsciousness
Copy link
Author

myConsciousness commented Apr 26, 2022

Thanks for your review and feedback @passsy !

I didn't know this fact, thanks for your testing! Then it would have to be classically recursively cloned, and also maybe it should be implemented in Object and with Clonable interface.

@myConsciousness
Copy link
Author

Okay I found a trick like below.

extension ListCloneExtension<E> on List<E> {
  /// Returns a deep copied list with the same elements as this [List].
  dynamic clone() => jsonDecode(jsonEncode(this));
}

This method uses serialization and deserialization, but the return type is dynamic. Also, this method does not seem to be versatile enough to be applied to Map. However, it can be used for List collections.

Can you give me your opinion on this method @passsy ?

@passsy
Copy link
Collaborator

passsy commented Apr 27, 2022

It only works for classes that are serializable. Unfortunately, there is no interface for it so that we can detect it reliably.

Your clone method wouldn't work for most classes that's why I don't see it as part of dartx. It's not general enough.

Let's wait for data classes or static metaprogramming or Algebraic Data Types to land in dart. These features might enable this feature.

@passsy passsy closed this Apr 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants