Dart

How can I delete duplicates in a Dart List listdistinct

27 September 2026 · 7 min read

How can I delete duplicates in a Dart List listdistinct

Managing data effectively is crucial in any application, and in Dart, working with collections like Lists is a daily task for developers. Often, you might find yourself with a List containing redundant entries, and the need to efficiently delete duplicates in a Dart List becomes a priority. While Dart doesn’t have a direct list.distinct() method as seen in some other languages’ LINQ-like extensions, it offers powerful and elegant solutions to achieve the same outcome. Understanding these methods is key to maintaining data integrity and optimizing your application’s performance. This guide will walk you through the most effective strategies, leveraging Dart’s built-in features to ensure your lists contain only unique elements, keeping your code clean and your data accurate.

Understanding Duplicates in Dart Lists and Why They Matter

A Dart List is an ordered collection of objects, allowing for duplicate entries by default. This behavior is perfectly fine for many use cases, such as tracking a sequence of events or storing multiple instances of the same item. However, there are numerous scenarios where duplicates can lead to incorrect logic, inefficient processing, or simply present misleading information to the user. For instance, if you’re populating a dropdown menu with unique options, displaying duplicate values would be redundant and confusing.

The presence of duplicates can also significantly impact performance, especially when dealing with large datasets. Iterating over a list that contains many identical items can consume unnecessary computational resources and slow down your application. Therefore, identifying and removing these redundant elements is a fundamental skill for any Dart developer. Efficiently filtering out duplicates ensures data accuracy, improves the user experience, and optimizes the overall performance of your Dart applications, whether you’re building a mobile app with Flutter or a backend service with Dart.

Consider a scenario where you’re fetching a list of product tags from a database. If the database query occasionally returns the same tag multiple times, you’ll want to process this list to ensure each tag is represented only once before displaying it to the user. This is where the techniques to remove duplicates become invaluable, transforming a potentially messy list into a clean, actionable collection of unique values.

Leveraging Dart Sets for Efficient Duplicate Removal

The most idiomatic and often the most efficient way to remove duplicates in a Dart List is by utilizing Dart’s Set collection. Unlike a List, a Set is an unordered collection of unique items. This fundamental characteristic makes it perfect for our goal: when you convert a List to a Set, all duplicate elements are automatically discarded, leaving only unique values. You can then convert this Set back into a List if you need to maintain the list structure for further operations.

This method is not only concise but also highly performant for most scenarios because Set implementations (like HashSet) typically offer O(1) average time complexity for adding elements. This means the time it takes to add an item doesn’t significantly increase with the size of the set, making it very efficient for processing large lists. If you need to retain the original order of the unique elements, Dart offers the LinkedHashSet, which maintains insertion order. However, for simply getting unique elements, HashSet is often sufficient and slightly faster.

According to the official Dart documentation on Sets, “A Set in Dart is an unordered collection of unique items.” This core principle is what we exploit to easily obtain a list of distinct elements. This approach covers the common need to find unique elements and implicitly addresses the “list.distinct()” query by offering Dart’s equivalent best practice.

Infographic here
Step-by-Step Implementation: Deleting Duplicates from a List ------------------------------------------------------------

The process of deleting duplicates from a Dart List is straightforward using the Set conversion. Here’s a detailed guide on how to implement this, along with considerations for different data types.

Method 1: Using toSet().toList() for Primitives

This is the simplest and most common method for lists of primitive types like integers, strings, or booleans. It’s concise and highly effective.

  1. Start with your List: Define the list containing potential duplicates.
  2. Convert to a Set: Call the toSet() method on your list. This creates a new Set containing only the unique elements.
  3. Convert back to a List: If you need the result as a List, call toList() on the resulting Set.
List<int> numbersWithDuplicates = [1, 2, 2, 3, 4, 4, 5, 1]; Set<int> uniqueNumbersSet = numbersWithDuplicates.toSet(); // {1, 2, 3, 4, 5} List<int> uniqueNumbersList = uniqueNumbersSet.toList(); // [1, 2, 3, 4, 5] print(uniqueNumbersList); // Output: [1, 2, 3, 4, 5] 

For maintaining the original order, use LinkedHashSet explicitly, though toSet() on a List typically returns a LinkedHashSet if the list is small enough to fit in memory efficiently. The Dart language is designed for developer convenience and performance, making this a highly optimized operation. This powerful pattern allows developers to efficiently unique elements Dart lists without complex manual iteration.

Method 2: Handling Custom Objects (Overriding hashCode and ==)

When your list contains custom objects, the toSet() method behaves differently. By default, Dart objects are compared by their identity (memory address). To ensure that two objects are considered “equal” (and thus duplicates) based on their content, you must override the == operator and the hashCode getter in your custom class.

Here’s why: when a Set checks for uniqueness, it first uses the hashCode to quickly find potential matches (in “buckets”) and then uses the == operator for a definitive comparison. If you only override ==, the Set might still treat logically identical objects as distinct because their hashCode values differ. Conversely, if hashCode is overridden but == isn’t, objects with the same hash code might still be considered distinct if their content isn’t truly equal.

The collection package is a valuable resource for Dart developers, offering utilities that can simplify overriding hashCode and ==, particularly with the hashValues helper function. This ensures that your custom objects are correctly identified as duplicates, aligning with your application’s logic. Correctly implementing these overrides is crucial for effectively managing data integrity with custom types in Dart.

class Person { final String name; final int age; Person(this.name, this.age); @override bool operator ==(Object other) { if (identical(this, other)) return true; return other is Person && other.name == name && other.age == age; } @override int get hashCode => Object.hash(name, age); // Efficient hashCode generation } void main() { List<Person> peopleWithDuplicates = [ Person('Alice', 30), Person('Bob', 25), Person('Alice', 30), // Duplicate Person('Charlie', 35), Person('Bob', 25), // Duplicate ]; List<Person> uniquePeople = peopleWithDuplicates.toSet().toList(); uniquePeople.forEach((p) => print('${p.name}, ${p.age}')); // Output: // Alice, 30 // Bob, 25 // Charlie, 35 } 

This specific implementation demonstrates how Dart collection manipulation can be powerful, but requires attention to detail when working with complex types. For a deeper dive into object equality in Dart, the Effective Dart guidelines provide excellent recommendations.

Advanced Scenarios and Performance Considerations

While toSet().toList() is generally the recommended approach for its simplicity and efficiency Question & Answer :

How do I delete duplicates from a list without fooling around with a set? Is there something like list.distinct()? or list.unique()?

void main() { print("Hello, World!"); List<String> list = ['abc',"abc",'def']; list.forEach((f) => print("this is list $f")); Set<String> set = new Set<String>.from(list); print("this is #0 ${list[0]}"); set.forEach((f) => print("set: $f")); List<String> l2= new List<String>.from(set); l2.forEach((f) => print("This is new $f")); } 
Hello, World! this is list abc this is list abc this is list def this is #0 abc set: abc set: def This is new abc This is new def 

Set seems to be way faster!! But it loses the order of the items :/

Use toSet and then toList

var ids = [1, 4, 4, 4, 5, 6, 6]; var distinctIds = ids.toSet().toList(); 

Result: [1, 4, 5, 6]

Or with spread operators:

var distinctIds = [...{...ids}]; 

Or to provide a more cast-iron guarantee that you retain ordering, use LinkedHashSet directly

as

var distinctIds = LinkedHashSet<int>.from(ids).toList() 

(NB “The default implementation of Set is LinkedHashSet” so it may not be strictly necessary)