Context
As javascript developers, we are constantly manipulating arrays of objects. And more often than not we want the data to be easily retrievable or simply well structured, like a directory would be. Now, suppose you have an array of objects representing books, and you want to quickly create an object where the keys are book titles and the values are the corresponding book objects. You can use the keyBy function to achieve this in a single line of code!
Usage
The keyBy function takes two arguments, an array and a key string (which could be made optional and default to the id property or whatever suits your use cases the most).
The reduce method is then used to iterate over each element of the provided array, creating a new object where the keys are based on the values of the parameter key in each object and the object itself as the value.
Let's make this more concrete with our books example:
// Primitives values
let books = [
"The Great Gatsby",
"To Kill a Mockingbird",
"Pride and Prejudice",
];
let booksByKey = keyBy(books);
// {
// "The Great Gatsby": "The Great Gatsby",
// "To Kill a Mockingbird": "To Kill a Mockingbird",
// "Pride and Prejudice": "Pride and Prejudice"
// }
// Object values
books = [
{ title: "The Great Gatsby", author: "F. Scott Fitzgerald", year: 1925 },
{ title: "To Kill a Mockingbird", author: "Harper Lee", year: 1960 },
{ title: "Pride and Prejudice", author: "Jane Austen", year: 1813 },
];
booksByKey = keyBy(books, "title");
// {
// 'The Great Gatsby': { title: 'The Great Gatsby', author: 'F. Scott Fitzgerald', year: 1925 },
// 'To Kill a Mockingbird': { title: 'To Kill a Mockingbird', author: 'Harper Lee', year: 1960 },
// 'Pride and Prejudice': { title: 'Pride and Prejudice', author: 'Jane Austen', year: 1813 }
// }
// And tada 🎉
booksByKey["The Great Gatsby"].author; // "F. Scott Fitzgerald"
This function doesn't handle the case where there are duplicated values, so it would just take the last encountered object for a certain value.
books = [
{ title: "The Great Gatsby", author: "F. Scott Fitzgerald", year: 1925 },
{ title: "To Kill a Mockingbird", author: "Harper Lee", year: 1960 },
{ title: "Pride and Prejudice", author: "Jane Austen", year: 1960 },
];
booksByKey = keyBy(books, "year");
// {
// 'The Great Gatsby': { title: 'The Great Gatsby', author: 'F. Scott Fitzgerald', year: 1925 },
// 'Pride and Prejudice': { title: 'Pride and Prejudice', author: 'Jane Austen', year: 1960 }
// }
Extension
Let's not stop here, we could easily extend our function to also handle objects of objects :
function collectionKeyBy(collection = {}, key) {
return Array.isArray(collection)
? keyBy(collection, key)
: keyBy(Object.values(collection), key);
}
The collectionKeyBy function builds upon the keyBy handling the case for both arrays and objects. It takes a collection as a first argument and a key string as the second argument, it then checks if the provided collection is an array using the isArray method. If it is, it calls the keyBy function directly, if not it will convert our collection to an array thanks to the Object.values method before calling the still great keyBy function. This code can be usefull if you wanna unwrap objects that are keyed randomly by an API, let say you get our books from an endpoint:
const books = {
book1: {title: 'The Great Gatsby', author: 'F. Scott Fitzgerald', year: 1925},
book2: {title: 'To Kill a Mockingbird', author: 'Harper Lee', year: 1960},
book3: {title: 'Pride and Prejudice', author: 'Jane Austen', year: 1813}
}
collectionKeyBy(books, "name");
// {
// "The Great Gatsby": {
// "title": "The Great Gatsby",
// "author": "F. Scott Fitzgerald",
// "year": 1925
// },
// "To Kill a Mockingbird": {
// "title": "To Kill a Mockingbird",
// "author": "Harper Lee",
// "year": 1960
// },
// "Pride and Prejudice": {
// "title": "Pride and Prejudice",
// "author": "Jane Austen",
// "year": 1960
// }
// }
Conclusion:
The keyBy supercharged by the collectionKeyBy function are useful utility functions that can be used to generate a key based directory from an array or an object of objects with flexibility and ease in mind. Happy coding!
Top comments (0)