Создать строку с объектами, сгруппированными по одному свойству - PullRequest
1 голос
/ 24 марта 2020

У меня есть класс со следующими свойствами:

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

My дальнейшее улучшение состоит в том, чтобы сгруппировать партии по их типу и поместить тип во множественное число, если есть больше одного и того же типа. В идеале строка должна выглядеть следующим образом:

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

Я мог бы использовать Словарь или Список, чтобы получить плюратор Типа, но я застрял в группировке партий и сохранении в строке partyinline один тип для сторон с одинаковым названием. Есть ли у вас какие-либо предложения с объяснениями?

Я прочитал Использование LINQ для группировки списка объектов и Использование Linq для группировки списка объектов в новый сгруппированный список списка объектов , но я застрял, я не могу определить шаги, чтобы получить желаемый результат.

Ответы [ 2 ]

1 голос
/ 24 марта 2020

Имеется словарь, в котором вы можете искать множественное число:

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

1 голос
/ 24 марта 2020

Вам нужно несколько звонков на string.Join. Обратите внимание:

  1. вы хотите объединить отдельные имена для каждой группы в одну строку для каждой группы,
  2. , а затем вы хотите объединить строки, сгенерированные из каждой группы, в одну строку.

Метод GroupBy имеет перегрузку, которая позволяет вам указать не только то, по чему вы группируете:

party => party.Type

, но и промежуточный результат для каждой группы; в этом случае одна строка:

(type, group) => $"{type} {String.Join(", ", group.Select(party => party.Name))}"
  • type - это то, на что группируется каждая группа (в данном случае значение в свойстве Type)
  • group - это сгруппированные экземпляры Party, свойство Name которого мы можем проецировать на последовательность строк (group.Select(party => 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<string, string>:

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 Скрипка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...