如何从dart中选择Map中的随机元素?

问题描述 投票:1回答:4

如何从Map中选择随机密钥(元素)?

我可以使用map.keys.toList()来完成它,如下面的代码所示,但我想知道是否有更直接的方法?

import "dart:math";

void main() {
    var map = {'a' :1, 'b':2, 'c':3};
    final _random = new Random();
    var keys = map.keys.toList();
    var element = keys[_random.nextInt(keys.length)];
    var r = map[element];
    print(r);
}
dart
4个回答
1
投票

如果您从列表中选择多个随机值,并且您希望确保永远不会多次选择一个条目,则可以将键或值作为列表,将其随机播放然后迭代它。

如果要选择地图中的一小部分条目,则效率不高。

void main() {

  var map = { 'a' :1, 'b':2, 'c':3 };

  // Keys
  var keys = map.keys.toList()..shuffle();  
  for(var k in keys) {
    print('$k, ${map[k]}');
  }

  // Values
  var values = map.values.toList()..shuffle();  
  for(var v in values) {
    print(v);
  } 
}

https://dartpad.dartlang.org/e49012d93f7451af1662ad113f0aab95


1
投票

没有简单的方法从地图中选择“随机”键。我认为这里的“随机”意味着在地图的键中随机均匀地选择它。

为此,您需要选择0..map.length - 1范围内的随机数。然后你需要获得相应的密钥。由于Map.key是一个可迭代的,你不能假设你可以在其中进行常量查找,但是你可以使用elementAt来获取特定的可迭代项而不创建新的列表。

所以,基本上:

randomKey(Map map) =>
    map.keys.elementAt(new Random().nextInt(map.length));

(就像你这样做,但没有toList)。

如果您需要多个密钥,最好将密钥转换为列表一次,然后在常量时间内在列表中进行查找。例:

Iterable randomKeys(Map map) sync* {
  var keys = map.keys.toList();
  var rnd = new Random();
  while (keys.length > 0) {
    var index = rnd.nextInt(keys.length);
    var key = keys[index];
    keys[index] = keys.last;
    keys.length--;
    yield key;
  }
} 

除了获得更好的性能之外,获取密钥的副本还可以避免并发修改错误。


0
投票

我想这不是你想要的,但实际上它是一条更短的线;-)

void main() {
    var map = {'a' :1, 'b':2, 'c':3};
    final _random = new Random();
    var values = map.values.toList();
    var element = values[_random.nextInt(values.length)];
    print(element);
}

DartPad example


0
投票

您可以使用dart_random_choice包来帮助您。虽然Map本身不是可迭代的,但您可以使用Map.keys方法获取可迭代并执行以下操作:

import 'package:dart_random_choice/dart_random_choice.dart';

void main() {
    var map = { 'a': 1, 'b': 2, 'c':3 };
    var r = map[randomChoice(map.keys)];
    print(r);
}
© www.soinside.com 2019 - 2024. All rights reserved.