-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
toMap() should take optional key/value selector functions #697
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
Comments
Related: #600 |
I started making a pull request, but there appear to be failing tests on master at the moment. This is the code I came up with to replace toMap(keySelector, valueSelector) {
// Use Late Binding here to solve the circular dependency.
// build a reducer that takes selector functions into account
var reducer = null;
if (keySelector && valueSelector)
reducer = (m, v, k) => m.set(keySelector(v, k), valueSelector(v, k));
else if (keySelector)
reducer = (m, v, k) => m.set(keySelector(v, k), v);
else if (valueSelector)
reducer = (m, v, k) => m.set(k, valueSelector(v, k));
// reduce required?
if (reducer === null)
return Map(this.toKeyedSeq());
// apply selector functions via reducer
return this.reduce(reducer, Map());
} |
This convenience method is going to be removed in a future version of Immutable as it can be confusing and currently restricts the ability to do incremental builds of Immutable. e.g. instead of doing: This also means if you would like a mapping function to construct the Map, you could write: |
Does I don't see how Removing |
Yep, I agree with you. What we're looking at is a tradeoff between chainability and modularity. Currently the library optimizes for chainability, but that means modularity isn't possible. As there's simultaneous demand for adding new kinds of data structures while also reducing the size of the library, we're stuck until the modularity problem is solved, and unfortunately that means giving up some chainability. Luckily, after surveying a large body of code that uses Immutable, conversion between different types is far from the most common of operations, so this should have relatively small impact on code quality and readability. |
It does! var list = Immutable.List([ 1, 2, 3 ]);
var map = Immutable.Map(list.map(v => [ v, v ]));
map.toString();
"Map { 1: 1, 2: 2, 3: 3 }" |
I think there is something wrong with the var m = Immutable.Map({ "10":100, "20":200 }).map((v, k) => [parseInt(k), v]);
m.toString();
// "Map { "10": 10,100, "20": 20,200 }" |
This issue and issues like it show we think converting between data types should less painful, but it looks like the project is going in the opposite direction. |
I'm sorry you feel that way @dubrowgn, my hope is to balance lots of different concerns for a best possible outcome. I understand that means tradeoffs in some places in order to accomplish other things. I certainly am not trying to actively move in a direction opposite from where issues are trying to highlight, on the contrary I'm trying to move in a direction that can satisfy as many as possible. Here I'm just trying to highlight that it's good news that your proposed code: data.toMap((item) => item.id, (item) => item.value); Can be written today as: Map(data.map(item => [ item.id, item.value ])); And that is both compatible with where the library's API is going in the future, and I hope is also not too detrimental to code legibility. |
My assumption with the example code above was that you were converting from a The var m = Immutable.Map({ "10":100, "20":200 }).mapEntries(([k, v]) => [parseInt(k), v]);
m.toString();
// "Map { 10: 100, 20: 200 }" |
Good to know, thanks! When using JSON to encode maps, int keys always come out as strings, so this kind of It seems strange that |
Common use case for easily indexing a sequence of data. It would basically work like this:
Currently you would probably use reduce:
The text was updated successfully, but these errors were encountered: