Skip to content

Support switch in Collection Literals #4354

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
rubenferreira97 opened this issue May 5, 2025 · 6 comments
Closed

Support switch in Collection Literals #4354

rubenferreira97 opened this issue May 5, 2025 · 6 comments
Labels
feature Proposed language feature that solves one or more problems

Comments

@rubenferreira97
Copy link

rubenferreira97 commented May 5, 2025

Dart supports if and for in collection literals, and even if-case. However, there's currently no support for switch inside collection literals, which limits expressiveness and leads to repeated expressions.

Example (today, using if-case):

final map = {
  for (final pair in pairs.split(';'))
    if (pair.split('=') case [final key]) key: '',
    else if (pair.split('=') case [final key, final value]) key: value,
};

This repeats split('=') and is harder to maintain (e.g. add cases).

Proposed (with switch support and implicit variables):

final map = {
  for (final pair in pairs.split(';'))
    switch (pair.split('=')) {
      case [final key]: key: '',
      case [final key, final value]: key: value,
    }
};

I believe switch in this context shouldn't require exhaustiveness—unmatched cases could simply be skipped, just like with if. If exhaustiveness is needed, a switch expression could be used instead.

I also understand that this level of logic might be considered too much for collection literals, but personally I've encountered cases where it would be useful. I'm filing this issue to open up discussion and gather feedback.

@rubenferreira97 rubenferreira97 added the feature Proposed language feature that solves one or more problems label May 5, 2025
@rrousselGit
Copy link

It is supported. But you used switch statements, yet you should use switch expressions.

The syntax is a little bit different:

final map = {
  for (final pair in ''.split(';'))
    ...switch (pair.split('=')) {
      [final key] => {key: ''},
      [final key, final value] => {key: value},
      [] => {},
    },
};

@rubenferreira97
Copy link
Author

rubenferreira97 commented May 5, 2025

Ye, I also found this workaround, but:

  1. The syntax feels heavier than it needs to be.
  2. I'm not sure if creating multiple intermediate sets/maps and spreading them is optimized.
  3. You need a default case (to spread nothing? 😅).

@mmcdon20
Copy link

mmcdon20 commented May 5, 2025

See also: #2124

@rubenferreira97
Copy link
Author

rubenferreira97 commented May 5, 2025

@mmcdon20 Thanks for pointing me to that issue. GitHub search can be really frustrating at times.

If we could inline a map entry (like 'key': 'value' in if statements), this might solve my problems for exhaustive cases:

enum Color { red, blue, yellow }

void main() {
  final color = Color.red;
  
  // Works fine
  final list = [
    switch (color) {
      Color.red => 'red',
      Color.blue => 'blue',
      Color.yellow => 'yellow',
    },
  ];

  // Works fine
  final set = {
    switch (color) {
      Color.red => 'red',
      Color.blue => 'blue',
      Color.yellow => 'yellow',
    },
  };

  // Error
  final map = {
    switch (color) {
      Color.red => 'a': 'red',
      Color.blue => 'b': 'blue',
      Color.yellow => 'c': 'yellow',
    },
  };
}

However, for non-exhaustive cases, there's no real solution because we have to be exhaustive in switch expressions and can't skip values:

final list = [
  for (final color in colors)
    switch (color) {
      Color.red => 'red',
      Color.blue => 'blue',
      _ => continue,
    },
];

@mateusfccp
Copy link
Contributor

  1. I'm not sure if creating multiple intermediate sets and spreading them is optimized.

It shouldn't be a problem. If you feel like this is a bottleneck try to identify if it is not being optimized, in which case you can open a bug report in the sdk repository.

@munificent
Copy link
Member

@mmcdon20 is right, #2124 is the main issue for this request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Proposed language feature that solves one or more problems
Projects
None yet
Development

No branches or pull requests

5 participants