分组结果"相当"使用LINQ [英] Grouping results "fairly" using LINQ

查看:126
本文介绍了分组结果"相当"使用LINQ的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的系统用户正在等待同一个帐户分配的列表。
分配算法非常简单,分配应尽可能公平,这意味着,如果我有40个账户和20个系统用户,我需要分配每个系统用户2帐户。
如果我有41的帐户和20系统用户我需要分配每个系统用户2帐户和再次分裂系统的用户之间的剩余账户(在这种情况下,一个系统的用户将与一个额外的帐户分配)。
我试图找出如何使用LINQ查询来做到这一点的同时,
到目前为止,我想通了分组应该参与,我的查询是:

I have a list of system users that are awaiting to be assigned with an account.
The assignment algorithm is very simple, assigning should be as fair as possible which means that if I have 40 accounts and 20 system users I need to assign 2 accounts per system user.
If I have 41 accounts and 20 system users I need to assign 2 accounts per system user and split the remaining accounts between the system users again (in this case, one system user will be assigned with one extra account).
I am trying to figure out how to do this while using a LINQ query.
So far I figured that grouping should be involved and my query is the following:

from account in accounts
    let accountsPerSystemUser = accounts.Count / systemUsers.Count
    let leftover = accounts.Count % systemUsers.Count
    from systemUser in systemUsers
        group account by systemUser into accountsGroup
select accountsGroup

不过我不清楚如何从这里出发。
我肯定,我很想念where子句在这里,将prevent分组,如果你达到了帐户的最高金额将分配给系统用户。 我如何实现查询正确的,这样的分组会知道多少来分配?

However I am uncertain how to proceed from here.
I am positive that I am missing a where clause here that will prevent grouping if you reached the maximum amount of accounts to be assigned to a system user. How do I implement the query correctly so that the grouping will know how much to assign?

推荐答案

下面是一个简单的实现,它的工作原理,如果你可以限制自己一个的IList< T> 帐户(你可以随时使用了ToList 虽然)。

Here is a simple implementation that works if you can restrict yourself to a IList<T> for the accounts (you can always use ToList though).

public static IEnumerable<IGrouping<TBucket, TSource>> DistributeBy<TSource, TBucket>(
    this IEnumerable<TSource> source, IList<TBucket> buckets)
{
    var tagged = source.Select((item,i) => new {item, tag = i % buckets.Count});
    var grouped = from t in tagged
                  group t.item by buckets[t.tag];
    return grouped;
}

// ...
var accountsGrouped = accounts.DistributeBy(systemUsers);

这基本上抓住每个帐户的指数和标签每个与指数的整数除以系统用户数量的剩余部分。这些标签是系统用户他们将属于的索引。然后,它只是群体他们通过该索引的系统用户。

Basically this grabs each account's index and "tags" each with the remainder of integer division of that index by the number of system users. These tags are the indices of the system users they will belong to. Then it just groups them by the system user at that index.

此可确保您的公平性的要求,因为零和一减去系统用户数量。之间的其余部分将周期

This ensures your fairness requirement because the remainder will cycle between zero and one minus the number of system users.

0 % 20 = 0
1 % 20 = 1
2 % 20 = 2
...
19 % 20 = 19
20 % 20 = 0
21 % 21 = 1
22 % 22 = 2
...
39 % 20 = 19
40 % 20 = 0

这篇关于分组结果&QUOT;相当&QUOT;使用LINQ的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆