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

时间:2016-06-08 11:24:55

标签: dart

如何从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);
}

4 个答案:

答案 0 :(得分: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 :(得分:1)

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

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

所以,基本上:

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

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

如果您需要 more 而不是一个键,那么您可能更好将密钥转换为列表一次,然后在常量时间内在列表中进行查找。例如:

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;
  }
} 

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

答案 2 :(得分: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

答案 3 :(得分: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);
}