如何从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);
}
如果您从列表中选择多个随机值,并且您希望确保永远不会多次选择一个条目,则可以将键或值作为列表,将其随机播放然后迭代它。
如果要选择地图中的一小部分条目,则效率不高。
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
没有简单的方法从地图中选择“随机”键。我认为这里的“随机”意味着在地图的键中随机均匀地选择它。
为此,您需要选择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;
}
}
除了获得更好的性能之外,获取密钥的副本还可以避免并发修改错误。
我想这不是你想要的,但实际上它是一条更短的线;-)
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);
}
您可以使用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);
}