2016-11-16 84 views
3

我有一本餐厅和一种餐厅的字典,如下所示:Dictionary<Restaurant, string>餐厅是我的班级,为了简单起见,我为我的餐馆类型使用了字符串。根据价值从字典中挑选随机条目

比方说,我在我的列表中有25个条目,其中可以有3,4或5个餐厅具有相同类型的组。现在我想缩小这个范围来为每个类型选择一个随机元素。

我找到了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>(); 

例如:可能的类型可以是ItalianFast foodSushi

我想询问另一个令人困惑的问题道歉。在发布内容之前,我会多加注意。

+1

请向我们提供一个[MCVE],显示您当前的代码是什么样子。 – dymanoid

+0

我认为这会更容易,如果你发布你的代码 – Yanga

+3

你的字典倒退。它应该从餐厅类型到餐厅列表。 – Amy

回答

1

第一个想法(这个列表的任何使用)。将您的数据源整理成一个更明智的格式,即,一个关键值结构,其中的密钥类型是标识餐馆子集(字符串)的东西,而价值是其中餐厅的列表。

为此,您可以使用代码类似于以下内容:

var sensibleDict = sillyDict 
    .GroupBy(kv => kv.Value) 
    .ToDictionary(
     m => m.Key, 
     m => m.Select(kv => kv.Key).ToList()); 

现在,我们可以简单地随机化的结果和采取的第一个随机化之后将其转换成一个密钥=>单值项目。

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

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)] 
} 
0

根据您所提供的链接,你可以使用接受IGrouping而不是扩展方法Dictionary(顺便说一句,为什么要用这样一个Dictionary可言,岂不是很简单的只是一个特性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(); 
+0

Rudi已经帮了我够多,但是为了阐述你的第一个问题,一家餐厅可以有多种类型。除了这个问题之外,因为我只想要每种类型的随机餐厅。这就是为什么我只在我的例子中使用了一个字符串 – RandomStranger