The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →To keep one object per property value, filter the array while tracking values in a Set. This keeps the first matching object and preserves input order. If you want the last matching object instead, use a Map and overwrite each key as you go.
Keep the first object for each property value
Use a generic helper when the property name is known and you want TypeScript to check that it exists on the objects:
As an Amazon Associate I earn from qualifying purchases.
function uniqueBy<T, K extends keyof T>(items: T[], key: K): T[] {
const seen = new Set<T[K]>();
return items.filter((item) => {
const value = item[key];
if (seen.has(value)) return false;
seen.add(value);
return true;
});
}
type User = { id: number; name: string };
const users: User[] = [
{ id: 1, name: "Ari" },
{ id: 2, name: "Bo" },
{ id: 1, name: "Ari (duplicate)" },
];
const uniqueUsers = uniqueBy(users, "id");
uniqueUsers contains the first object with id: 1 and the object with id: 2. The type parameter K extends keyof T restricts key to a property of the item type, while Set<T[K]> tracks values of that property’s type. TypeScript’s object types describe this compile-time relationship; the Set behavior is provided by JavaScript. See the TypeScript object types handbook and MDN’s Set reference.
Recommended Free Tools
- The function returns a new array and does not mutate the input array or its objects.
- It preserves the original order of the retained objects because
filtervisits items from first to last. - It keeps the original object references; it does not clone or merge them.
Keep the last object for each property value
When the later object should replace the earlier one, store each item in a Map under the selected property value:
#1 Best Overall
function uniqueByLast<T, K extends keyof T>(items: T[], key: K): T[] {
const byKey = new Map<T[K], T>();
for (const item of items) byKey.set(item[key], item);
return [...byKey.values()];
}
Setting a key already in the map replaces its associated value. The returned array therefore contains the last object encountered for each value. Map iteration follows key insertion order: a key keeps the position where it was first inserted, even when its value is later replaced. See MDN’s Map reference.
Choose the approach that matches the result you need
| Approach | Result | Order |
|---|---|---|
filter plus Set |
First object for each selected value | Order of retained objects in the input |
Map overwrite |
Last object for each selected value | First-insertion order of distinct keys |
Map.groupBy |
Arrays containing all objects for each group | Groups are keyed by first occurrence; objects remain grouped in input order |
Map.groupBy is useful when you need every object in each group rather than one representative. It does not deduplicate the group for you. TypeScript 5.4 added declarations for JavaScript’s Object.groupBy and Map.groupBy; verify that your TypeScript lib configuration and runtime support the API, because type declarations do not add support to an older runtime. See the TypeScript 5.4 release notes.
Rank #2
- TypeScript implements a superset of syntax for strictly typed development, facilitating deep static analysis and enhanced development environment integration. The compiler translates source into standard script formats, ensuring parity across any runtime.
- TypeScript is ideal for front-end developers, full-stack engineers, and software architects who build large-scale web applications. It serves those looking to improve code excellence, reduce bugs through static checking, and maintain complex projects more.
- Lightweight, Classic fit, Double-needle sleeve and bottom hem
What counts as the same key?
For primitive values, Set and Map use SameValueZero equality: NaN matches NaN, and positive and negative zero count as equal. If the selected property contains objects, equality is by reference identity, not by matching fields. These behaviors are described in the Map, Set, and keyed collections references.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchPC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11A Set of whole objects will therefore remove repeated references to the same object, but not distinct objects that merely have equal properties:
const a = { id: 1 };
const values = new Set([a, a, { id: 1 }]);
// The set contains two objects: the repeated reference and the new object.
For a composite key, a freshly created object or tuple will not work as a structural key: each new object has a distinct reference. Use a stable primitive encoding only if it unambiguously represents the fields, or use nested maps when fields have mixed types. A simple delimiter join can collide if a field value can contain that delimiter.
Decide how to handle missing, null, or differently formatted values
The generic helper treats every observed key value according to the collection’s equality rules. If several items have an undefined or null key, they belong to the same group. If that is not the intended policy, filter those records out or handle them separately before selecting representatives.
For case-insensitive string keys, normalize the value before adding it to seen or using it as the map key, for example with value.toLowerCase(). If the property may be absent or non-string, narrow or validate its type first.
Free tools Windows power users keep installed
One-click scans. No signup required.
Object-valued properties require an explicit structural matching rule if objects with equivalent contents should count as duplicates. JSON serialization is not a universal substitute: field ordering, unsupported values, and the meaning of equivalence can affect the result.
Best Value
Performance expectations
MDN documents average access for Map and Set as sublinear in collection size, but the JavaScript specification does not guarantee an exact constant-time implementation. Runtime and data shape matter, so avoid claiming a precise speedup without measuring the workload that matters to your application.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




