Skip to content

proposal: maps: add analogues to Keys/Values that return slices #72909

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

Closed
kwjw opened this issue Mar 17, 2025 · 6 comments
Closed

proposal: maps: add analogues to Keys/Values that return slices #72909

kwjw opened this issue Mar 17, 2025 · 6 comments
Labels
LibraryProposal Issues describing a requested change to the Go standard library or x/ libraries, but not to a tool Proposal
Milestone

Comments

@kwjw
Copy link

kwjw commented Mar 17, 2025

Proposal Details

If a program requires a slice of a map's keys or values, there are some options:

  1. Call the nice-looking but poorly-performing slices.Collect(maps.Values(m)) (which has unnecessary allocations).
  2. Call the accurate but ugly slices.AppendSeq(make([]K, 0, len(m)), maps.Values(m)) (or, more realistically, write this as a function). Edited to add: Even better, you'd write a function that iterates over the map manually instead of calling the iter-based methods at all.
  3. Use x/exp/maps instead, where Keys/Values return slices (obviously not ideal).

Proposal: add standard library functions (maybe call them maps.KeysSlice or maps.ValuesSlice) to return a slice of map keys or values respectively.

@kwjw kwjw added the Proposal label Mar 17, 2025
@gopherbot gopherbot added this to the Proposal milestone Mar 17, 2025
@DeedleFake
Copy link

DeedleFake commented Mar 17, 2025

Another option would be to add a slices.CollectN[T any](seq iter.Seq[T], n int) that would preallocate a slice of a specific capacity for you to give an in-between for options 1 and 2. I'm not thrilled with the name because it kind of sounds like it limits how many it collects, but the idea is the point.

@kwjw
Copy link
Author

kwjw commented Mar 17, 2025

To be sure, I am ambivalent about my own proposal.

On one hand, this is such a straightforward function to implement that it might not be worth expanding API surface for.

On the other hand, I generally think it's a good idea for the stdlib to make it easy to do the right thing.

@kwjw
Copy link
Author

kwjw commented Mar 17, 2025

Another option would be to add a slices.CollectN[T any](seq iter.Seq[T], n int) that would preallocate a slice of a specific capacity for you to give an in-between for options 1 and 2.

This would still have some overhead from the repeated function calls involved in iterators. A pre-allocated version of Collect could be a nice middle ground, but I see value in allowing a totally cost-free migration path from the x/exp/maps sliced-based functions for callers who value its performance.

@gabyhelp gabyhelp added the LibraryProposal Issues describing a requested change to the Go standard library or x/ libraries, but not to a tool label Mar 17, 2025
@icholy
Copy link

icholy commented Mar 17, 2025

@DeedleFake what about something like AppendCollect where you can pass the destination slice?

@DeedleFake
Copy link

@icholy

That already exists under the name slices.AppendSeq(). The original proposal mentions it as option 2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
LibraryProposal Issues describing a requested change to the Go standard library or x/ libraries, but not to a tool Proposal
Projects
None yet
Development

No branches or pull requests

6 participants