C# 基于值从字典中随机选取条目

C# 基于值从字典中随机选取条目,c#,dictionary,random,C#,Dictionary,Random,我有一本关于餐馆的字典,还有一种餐馆类型,像这样:dictionaryWhere restaurants是我的职业,为了简单起见,我用字符串表示我的餐馆类型 假设我的列表中有25个条目,其中可以有3个、4个或5个相同类型的餐厅。现在我想缩小范围,为每种类型选择一个随机元素 我找到了一个页面,它解释了如何从字典中随机选取值,但我该如何在每一组类型中随机选取一个条目呢 让我知道,如果我应该详细说明或如果你需要更多的信息 编辑:我的代码示例: Dictionary<Restaurant, str

我有一本关于餐馆的字典,还有一种餐馆类型,像这样:
dictionary
Where restaurants是我的职业,为了简单起见,我用字符串表示我的餐馆类型

假设我的列表中有25个条目,其中可以有3个、4个或5个相同类型的餐厅。现在我想缩小范围,为每种类型选择一个随机元素

我找到了一个页面,它解释了如何从字典中随机选取值,但我该如何在每一组类型中随机选取一个条目呢

让我知道,如果我应该详细说明或如果你需要更多的信息

编辑:我的代码示例:

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>();
Dictionary=newdictionary();
randomRestaurants.Add(restaurants.GroupBy(x=>x.string)。//在每个分组中随机选取一个条目,并将其添加到列表中//
列表=新列表();
例如:可能的类型可以是
意大利
快餐
寿司

我很抱歉问了另一个让人困惑的问题。在发布内容之前,我会更加注意。

请尝试以下方法:

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)]
}
var restaurants=new Dictionary第一个想法(对于此列表的任何用法)是将数据源排序为更合理的格式,即键值结构,其中键类型是标识餐厅子集(字符串)的内容,值是其中餐厅的列表

您可以使用类似于以下内容的代码执行此操作:

var sensibleDict = sillyDict
    .GroupBy(kv => kv.Value)
    .ToDictionary(
        m => m.Key,
        m => m.Select(kv => kv.Key).ToList());
现在,我们可以简单地将结果随机化,并将随机化后的第一个结果转换为Key=>单值项

var randomDict = sillyDict
    .GroupBy(kv => kv.Value)
    .ToDictionary(
        m => m.Key,
        m => m.Select(kv => kv.Key)
            .OrderBy(k => Guid.NewGuid())
            .Take(1)
            .First());
这将得到一个
词典
,其中第一个字符串是食物类型(即意大利、寿司),第二个字符串是随机的
餐厅


注意:正如我在评论中所说的,如果数据集变大,这并不是排序列表的最有效方法。要获得更好的列表无序排列方法,请查看。

根据您提供的链接,您可以使用扩展方法进行
I分组
,而不是使用
字典
(顺便说一句,为什么要以这种方式使用
词典
,将属性
RestaurantType
添加到
餐厅
类中不是更简单吗?)

公共静态类Ext
{
公共静态IEnumerable随机值(此I分组,int计数)
{
Random rand=新的Random();
列表值=grouping.ToList();
整数大小;
而(计数>0&&values.count>0)
{
大小=值。计数;
var v=值[下一个随机数(大小)];
删除(v);
计数--;
收益率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();
//示例数据
字典=新字典();
添加(新餐厅(“r1”),“A”);
添加(新餐厅(“r2”),“B”);
添加(新餐厅(“r3”),“A”);
添加(新餐厅(“r4”),“B”);
添加(新餐厅(“r5”),“A”);
添加(新餐厅(“r6”),“B”);
添加(新餐厅(“r7”),“A”);
添加(新餐厅(“r8”),“B”);
//A组随机抽取3家餐厅
列出randomRestaurants=restaurants.GroupBy(a=>a.Value).FirstOrDefault(a=>a.Key==“a”)
.RandomValues(3).选择(x=>x.Key).ToList();
1.Clear();
//每组1间随机餐厅
列出随机餐厅2=餐厅
.GroupBy(a=>a.Value)
.Select(a=>a.RandomValues(1).FirstOrDefault().Key)
.ToList();
//或者,使用SelectMany,每种类型随机选择2家餐厅:
List randomRestaurants3=restaurants.GroupBy(a=>a.Value)
.SelectMany(a=>a.RandomValues(2))
.Select(d=>d.Key).ToList();

请为我们提供一个可以显示您当前代码的列表。我认为如果您发布代码,您的字典是向后的,这会更容易。它应该从餐厅类型到餐厅列表。要基于您的字典执行此操作,请先将其转换为
字典
,以便您可以使用它。您可以通过这样做让它变得更有意义:
var sensibleDict=sillyDict.GroupBy(kv=>kv.Value).ToDictionary(m=>m.Key,m=>m.Select(kv=>kv.Key.ToList());
然后你可以简单地随机列表(使用一种方法,比如按Guid排序)。我会写一个快速的答案(注意,这可能不是最有效的方法)Rudi已经帮了我很多,但要详细说明你的第一个问题,一家餐厅可以有多种类型。这是问题之外的问题,因为我只希望每种类型都有一家随机餐厅。这就是为什么我在示例中只使用字符串的原因
       // 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();