【问题标题】:Create string with Objects grouped by same Property使用按相同属性分组的对象创建字符串
【发布时间】:2020-03-24 09:06:52
【问题描述】:

我有一个具有以下属性的类:

public class Party
{
    public string Type { get; set; }
    public string Name { get; set; }
}

还有这个填充列表的方法:

List<Party> parties = new List<Party>();
parties.Add(new Party {Type = "Plaintiff", Name = "Eilean Dover"});
parties.Add(new Party {Type = "Plaintiff", Name = "Bea O'Problem"});
parties.Add(new Party {Type = "Defendant", Name = "Anna Graham"});
parties.Add(new Party {Type = "Witness", Name = "John Doe"});
parties.Add(new Party {Type = "Witness", Name = "Rosa Shore"});

我的目标是将所有对象(各方)放在一个字符串中。 到目前为止,我已经使用 String.Join 和 Linq 将它们内联。

string partiesinline = string.Join(", ", parties.Select(x => String.Join(" ", new[] { x.Type, x.Name })));

运行后,字符串partiesinline 如下所示:

Plaintiff Eilean Dover, Plaintiff Bea O'Problem, Defendant Anna Graham, Witness John Doe, Witness Rosa Shore

我的进一步改进是按类型对各方进行分组,如果有更多相同类型,则将类型设为复数形式。 理想情况下,字符串应如下所示:

Plaintiffs Eilean Dover, Bea O'Problem, Defendant Anna Graham and Witnesses John Doe, Rosa Shore

我可以使用字典或列表来获取类型的复数,但我被困在对各方进行分组并在partyinline 字符串中为具有相同名称的各方保留单一类型。 你有什么建议和解释吗?

我已阅读 Using LINQ to group a list of objectsUsing Linq to group a list of objects into a new grouped list of list of objects 但我被卡住了,我无法识别步骤以获得所需的结果。

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    您需要多次致电string.Join。考虑:

    1. 您想将每个组的单个名称组合成一个字符串,每个组,
    2. 然后您想将每个组生成的字符串组合成一个字符串。

    GroupBy 方法有一个重载,它不仅可以让您指定分组依据:

    party => party.Type
    

    但是每个组的中间结果;在这种情况下,单个字符串:

    (type, group) => $"{type} {String.Join(", ", group.Select(party => party.Name))}"
    
    • type 是每个组的分组依据(在本例中为 Type 属性中的值)
    • groupParty 的分组实例,我们可以将其 Name 属性投影到字符串序列 (group.Select(party =&gt; party.Name),然后我们可以使用 String.Join 将其连接成单个字符串。

    总共:

    var grouping = parties.GroupBy(
        party => party.Type,
        (type, group) => $"{type} {String.Join(", ", group.Select(party => party.Name))}"
    );
    

    grouping 现在可以为我们提供一系列字符串,我们可以再次将其与String.Join 一起使用来创建单个字符串:

    var result = string.Join(",", grouping);
    

    至于复数类型,我认为您通常可以添加s,但将此规则的例外情况放在Dictionary&lt;string, string&gt;中:

    private static Dictionary<string, string> specialPlurals = new Dictionary<string, string> {
        {"Witness", "Witnesses"}
    };
    

    然后,编写一个函数,为您提供适当的复数:

    public static string Pluralize(string singular) {
        if (string.IsNullOrWhiteSpace(singular)) { return singular;}
        if (specialPlurals.TryGetValue(singular, out var plural)) { return plural;}
        return $"{singular}s";
    }
    

    并按如下方式使用:

    var grouping = parties.GroupBy(
        party => party.Type,
        (type, group) => $"{Pluralize(type)}: {String.Join(", ", group.Select(party => party.Name))}"
    );
    var result = string.Join("; ", grouping);
    

    这会生成以下内容:

    Plaintiffs: Eilean Dover, Bea O'Problem; Defendants: Anna Graham; Witnesses: John Doe, Rosa Shore
    

    .NET Fiddle

    【讨论】:

    • 虽然 Jamiec 提供的答案对我的测试来说已经足够了,但你的步骤很详细,而且它是供进一步使用的好文档。谢谢!
    【解决方案2】:

    给定一本字典,您可以在其中查找复数:

    Dictionary<string,string> plurals = new Dictionary<string,string>{
        ["Plaintiff"] = "Plaintiffs",
        ["Defendant"] = "Defendants",
        ["Witness"] = "Witnesses"
    };
    

    您可以使用以下代码:

    var result = string.Join(", ", parties.GroupBy(x => x.Type).Select(item => {
        var prefix = item.Count()>1 ? plurals[item.Key] : item.Key;
        var people = String.Join(", ", item.Select(x => x.Name));
        return $"{prefix} {people}";
    }));
    

    现场示例:https://dotnetfiddle.net/wCVgeB

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-12
      • 2022-11-26
      • 2021-12-24
      • 1970-01-01
      • 2012-06-27
      • 1970-01-01
      • 2017-07-26
      • 2021-09-12
      相关资源
      最近更新 更多