Skip to content

Problems with Enumerable#map_by #75

@tokland

Description

@tokland

I use Enumerable#map_by a lot, it's a great abstraction because, more often than not, Enumerable#group_by falls too short. However, there are a couple of closely related problems with its implementation and specifications:

  1. Implementation: insufficient checks of the returned value of the block:
[[:a, true], [:b, false], [:c, nil]].map_by { |x, y| [x, y] }
#=> {:a=>[true], :b=>[[:b, false]], :c=>[[:c, nil]]}

Would'n you expect {:a=>[true], :b=>[false], :c=>[nil]}?

  1. Specifications: "if a second value is not returned, #map_by acts like #group_by.". The problem is that you cannot tell an array (which you may intent to use as a key) from a pair [key, value]. You may for example write:
[1, 2, 3].map_by { |x| [x, 2*x] }
#=> {1=>[2], 2=>[4], 3=>[6]}

But what you expected was {[1, 2]=>[1], [2, 4]=>[2], [3, 6=>[3]}. The old Unix adagio probably applies: "do one thing and do it well".


It looks to me that while (1) is easily solvable, (2) suggests that trying to act like group_by was a bad idea after all (if you wanted a group_by shouldn't you be using group_by anyway?). Granted, that change would break some old code (though I am not sure many people were actually using map_by that way...).

I can prepare a pull request with the conclusion of the conversation, I wanted to gather some opinions first.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions