-
Notifications
You must be signed in to change notification settings - Fork 4
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
Add map actions for multiple items #6
Add map actions for multiple items #6
Conversation
I couldn't run the tests. They kept failing with:
Even after I installed
|
Hi Benjamin, Thanks a lot for submitting this PR!
|
Regarding the design, how about this: addChangeItemsGetter = action => action.payload.reduce((a, e) => {a[e.id] = e; return a;}, {})
removeKeysGetter = action => action.payload
What do you think? |
addChangeItemsGetter = action => action.payload.reduce((result, item) => ({ | ||
...result, | ||
[item.id]: item | ||
}), {}), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an unnecessary use of immutability: the accumulator
's scope inside Array.prototype.reduce
's callback
is well defined. We can safely mutate it. The immutable solution is actually very slow compared to the mutable solution I suggested: https://jsperf.com/mutable-vs-immutable-reduce
I know that redux-data-structures doesn't focus on performance (https://github.com/adrienjt/redux-data-structures#performance), but this is a low hanging fruit.
If you're interested in the details, I suggest running the two snippets with node --prof
. You'll see that the immutable solution spends most of its time copying arrays:
[Summary]:
ticks total nonlib name
104 0.1% 0.1% JavaScript
77095 85.7% 85.9% C++
242 0.3% 0.3% GC
179 0.2% Shared libraries
12573 14.0% Unaccounted
[C++ entry points]:
ticks cpp total name
76917 99.9% 85.5% T v8::internal::Runtime_CopyDataProperties(int, v8::internal::Object**, v8::internal::Isolate*)
const addMany = (state, action, addChangeItemsGetter) => { | ||
const items = addChangeItemsGetter(action) | ||
return Object.keys(items).reduce((result, key) => { | ||
return addItem(result, key, items[key]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like your attempt at factorizing some code here. But the performance impact is O(n). Now that addChangeItemsGetter returns the items as a map-Object, you can merge them all at once:
const addMany = (state, action, addChangeItemsGetter) => {
const items = addChangeItemsGetter(action);
const keys = Object.keys(items);
return {
byId: {...state.byId, ...items},
allIds: [...new Set(state.allIds.concat(keys))],
};
}
changeMany
and removeMany
could use similar optimizations.
How about |
I'm closing this as I no longer use this module so don't have the need for this. |
This adds
addMany...
andremoveMany...
actions tomap
. These actions can be used to add multiple items to the map with only one action.For this, three other options where added:
collectionGetter = action => [...action.payload]
collectionItemGetter = item => ({ ...item })
collectionKeyGetter = item => item.id
Closes #5.