There is some very bad naming in the code. Names are too long and have overlapping abstractions. What is a category, there are two types a
, b
, or c
and testnum1
and itemNum2
Due to poor naming the function has lost so much semantic accuracy it takes a second look to see what it is doing.
What are you doing?
getCategorizedItems
getting categorized items??
From the input example all items are already categorized. So the function is not really getting categorized items
The output has new categories "a"
becomes "test123"
so the items are being recategorized (or because there is a one to one match the cats are being transformed)
Each item is restructured, From {name: 'test', value: 1, category: 'a'}
to {name: 'test', category: 'testnum1'}
Items are filtered by existence of transformed category names.
Rename
Naming the function transformCategoriesRestructureAndFilter
is impractical so recategorize
could be more apt within the context of the code
As you are using category
as an identifier, you should make it clear categoryId
or catId
, or even just id
. Thus
// ignoring irrelevant data
itemList = {testnum1: {catId: 'a'}, testnum2: {catId: 'b'}};
items = [{name: '1', catId: 'a'},{name: '2', catId: 'b'},{name: '3', catId: 'c'}];
Use appropriate data structures
The object itemList
is a transformation and should be a Map for quick lookup. Either defined as such
const catIdTransform = new Map((["a", "testnum1"], ["b", "testnum2"]]);
Or constructed from itemList
const catIdTransform = new Map(Object.entries(itemList).map(([name, {catId}]) => [catId, name]));
Rewrite
Thus you can rewrite using the new naming.
First transform the catId
and then filter items without new ids.
function recategorize(items, idMap) {
return items.map(item => ({...item, catId: idMap.get(item.catId)}))
.filter(({catId}) => catId);
}
Working example
Using renamed data structures.
const items = [{name: '1', catId: 'a'},{name: '2', catId: 'b'},{name: '3', catId: 'c'}];
const catIdTransform = new Map([["a", "num1"], ["b", "num2"]]);
function recategorize(items, idMap) {
return items.map(item => ({...item, catId: idMap.get(item.catId)}))
.filter(({catId}) => catId);
}
console.log(recategorize(items, catIdTransform));
or if you are forced to maintain the naming and existing data
const items = [{name: '1', category: 'a'}, {name: '2', category: 'b'}, {name: '3', category: 'c'}];
const itemList = {testnum1: {category: 'a'}, testnum2: {category: 'b'}};
const categoryTransform = new Map(Object.entries(itemList).map(([name, {category}]) => [category, name]));
function categorizedItems(items, idMap) { // at least drop the get
return items.map(item => ({...item, category: idMap.get(item.category)}))
.filter(({category}) => category);
}
console.log(categorizedItems(items, categoryTransform));