Linq2sql:获得具有权重的随机元素的有效方法? [英] Linq2sql: efficient way to get random elements with weight?
问题描述
可以说我有一个整数权重,即权重为10的元素的选择概率是权重为1的元素的10倍.
Byt lets say I have an integer weight where i.e. elements with weight 10 has 10 times higher probability to be selected than element with weight 1.
var ws = db.WorkTypes
.Where(e => e.HumanId != null && e.SeoPriority != 0)
.OrderBy(e => /*????*/ * e.SeoPriority)
.Select(e => new
{
DescriptionText = e.DescriptionText,
HumanId = e.HumanId
})
.Take(take).ToArray();
当我需要对结果进行加权时,如何解决在Linq中获取随机记录的问题?
How do I solved getting random records in Linq when I need the result to be weighted?
我需要类似 T-SQL中的随机加权选择之类的东西,但在linq不仅获得一项记录?
I need somthing like Random Weighted Choice in T-SQL but in linq and not only getting one record?
如果我没有加权要求,我会使用NEWID方法,可以采用这种方式吗?
If I wouldn't have the weighted requirement, I'd use the NEWID approach, can I adopt this some way?
partial class DataContext
{
[Function(Name = "NEWID", IsComposable = true)]
public Guid Random()
{
throw new NotImplementedException();
}
}
...
var ws = db.WorkTypes
.Where(e => e.HumanId != null && e.SeoPriority != 0)
.OrderBy(e => db.Random())
.Select(e => new
{
DescriptionText = e.DescriptionText,
HumanId = e.HumanId
})
.Take(take).ToArray();
推荐答案
我的第一个想法与罗恩·克莱因(Ron Klein)的想法相同-创建一个加权列表并从中随机选择.
My first idea was the same as Ron Klein's - create a weighted list and select randomly from that.
这是一种LINQ扩展方法,可以通过已知对象的weight属性的lambda函数从普通列表创建加权列表.
Here's a LINQ extension method to create the weighted list from the normal list, given a lambda function that knows the weight property of the object.
请放心,如果您没有立即获得所有的泛型信息,请按照以下用法进行操作:
Don't worry if you don't get all the generics stuff right away... The usage below should make it clearer:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
public class Item
{
public int Weight { get; set; }
public string Name { get; set; }
}
public static class Extensions
{
public static IEnumerable<T> Weighted<T>(this IEnumerable<T> list, Func<T, int> weight)
{
foreach (T t in list)
for (int i = 0; i < weight(t); i++)
yield return t;
}
}
class Program
{
static void Main(string[] args)
{
List<Item> list = new List<Item>();
list.Add(new Item { Name = "one", Weight = 5 });
list.Add(new Item { Name = "two", Weight = 1 });
Random rand = new Random(0);
list = list.Weighted<Item>(x => x.Weight).ToList();
for (int i = 0; i < 20; i++)
{
int index = rand.Next(list.Count());
Console.WriteLine(list.ElementAt(index).Name);
}
Console.ReadLine();
}
}
}
从输出中可以看到,结果是随机的,也可以根据需要加权.
As you can see from the output, the results are both random and weighted as you require.
这篇关于Linq2sql:获得具有权重的随机元素的有效方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!