我有一张餐馆的字典和一种类似这样的餐馆:Dictionary<Restaurant, string>
餐馆是我的班级,为了简单起见,我在餐馆用字符串。
假设我的列表中有25个条目,其中可以有3个,4个或5个相同类型的餐馆。现在我想缩小范围,以便为每种类型选择1个随机元素。
我找到了this页面,其中解释了如何从字典中选择随机值,但是如何根据类型分组选择随机条目?
如果我需要详细说明或者您是否需要其他信息,请告诉我们!
编辑:我的代码示例:
Dictionary<Restaurant, string> restaurants = new Dictionary<Restaurant, string>();
randomRestaurants.Add(restaurants.GroupBy(x => x.string).//Randomly pick an entry per grouping and add it to list//
List<Restaurant> randomRestaurants = new List<Restaurant>();
例如:可能的类型可以是Italian
,Fast food
和Sushi
我想就另一个令人困惑的问题道歉。在发布内容之前,我会更加关注。
答案 0 :(得分:1)
第一个想法(对于此列表的任何用法)是将您的数据源命令为更合理的格式,即键值结构,其中键类型是标识餐馆子集的字符串(字符串),并且值是其中的餐馆列表。
您可以使用类似于以下内容的代码执行此操作:
var sensibleDict = sillyDict
.GroupBy(kv => kv.Value)
.ToDictionary(
m => m.Key,
m => m.Select(kv => kv.Key).ToList());
现在,我们可以简单地将结果随机化并在随机化后取第一个将其转换为Key =&gt;单值项目。
var randomDict = sillyDict
.GroupBy(kv => kv.Value)
.ToDictionary(
m => m.Key,
m => m.Select(kv => kv.Key)
.OrderBy(k => Guid.NewGuid())
.Take(1)
.First());
这会得到Dictionary<string, Restaurant>
,其中第一个字符串是食物类型(即意大利语,寿司),第二个字符串是随机Restaurant
。
注意:正如我在评论中所说,如果您的数据集变大,这不是订购列表的最有效方式。有关改组列表的更好方法,请查看at this answer - Randomise a List。
答案 1 :(得分:0)
尝试这种方式:
var restaurants = new Dictionary<string, List<Restaurant>();
//when u want to add a restaurant do this way:
var restaurant = new Restaurant { Type = "Sushi" };
List<Restaurant> res;
if(restaurants.TryGet(restaurant.Type, out res){
res.Add(restaurant);
}
else restaurants.Add(restaurant.Type, new List<Restaurant> { restaurant });
// get random from a type
List<Restaurant> res2;
var type = "Sushi";
if(restaurants.TryGet(type, out res2){
return res2[rand.Next(res2.Count)]
}
答案 2 :(得分:0)
根据您提供的链接,您可以使用IGrouping
代替Dictionary
的扩展方法(顺便说一句。为什么要以这种方式使用Dictionary
,不会&# 39;只是将属性RestaurantType
添加到Restaurant
类更简单吗?)
public static class Ext
{
public static IEnumerable<TValue> RandomValues<TKey, TValue>(this IGrouping<TKey, TValue> grouping, int count)
{
Random rand = new Random();
List<TValue> values = grouping.ToList();
int size;
while (count>0 && values.Count>0)
{
size = values.Count;
var v = values[rand.Next(size)];
values.Remove(v);
count--;
yield return v;
}
}
}
使用代码:
// example data
Dictionary<Restaurant, string> restaurants = new Dictionary<Restaurant, string>();
restaurants.Add(new Restaurant("r1") ,"A");
restaurants.Add(new Restaurant("r2") ,"B");
restaurants.Add(new Restaurant("r3") ,"A");
restaurants.Add(new Restaurant("r4") ,"B");
restaurants.Add(new Restaurant("r5") ,"A");
restaurants.Add(new Restaurant("r6") ,"B");
restaurants.Add(new Restaurant("r7") ,"A");
restaurants.Add(new Restaurant("r8") ,"B");
// 3 Random restaurants from group "A"
List<Restaurant> randomRestaurants = restaurants.GroupBy(a=>a.Value).FirstOrDefault(a=>a.Key=="A")
.RandomValues(3).Select(x=>x.Key).ToList();
randomRestaurants.Clear();
// 1 random restaurant per group
List<Restaurant> randomRestaurants2 = restaurants
.GroupBy(a => a.Value)
.Select(a => a.RandomValues(1).FirstOrDefault().Key)
.ToList();
// or, with SelectMany, 2 random restaurants per type:
List<Restaurant> randomRestaurants3 = restaurants.GroupBy(a => a.Value)
.SelectMany(a => a.RandomValues(2))
.Select(d=>d.Key).ToList();