Самый простой способ объединить два списка <T>с - PullRequest
1 голос
/ 16 марта 2010

У меня есть два List<Name> с:

public class Name
        {
            public string NameText {get;set;}
            public Gender Gender { get; set; }
        }

public class Gender
        {
            public decimal MaleFrequency { get; set; }
            public decimal MaleCumulativeFrequency { get; set; }
            public decimal FemaleCumulativeFrequency { get; set; }
            public decimal FemaleFrequency { get; set; }
        }

Если свойство NameText совпадает, я бы хотел взять FemaleFrequency и FemaleCumulativeFrequency из списка женских Name s и значения MaleFrequency и MaleCumulativeFrequency из списка мужских Name s и создайте один список Name s со всеми заполненными четырьмя свойствами.

Какой самый простой способ сделать это в C # с использованием .Net 3.5?

Ответы [ 3 ]

5 голосов
/ 16 марта 2010

Вы пытаетесь суммировать каждое из значений при объединении списков? Если это так, попробуйте что-то вроде этого:

List<Name> list1 = new List<Name>();
List<Name> list2 = new List<Name>();

List<Name> result = list1.Union(list2).GroupBy(x => x.NameText).Select(x => new
Name
{
    NameText = x.Key,
    Gender = new Gender
    {
        FemaleCumulativeFrequency = x.Sum(y => y.Gender.FemaleCumulativeFrequency),
        FemaleFrequency = x.Sum(y => y.Gender.FemaleFrequency),
        MaleCumulativeFrequency = x.Sum(y => y.Gender.MaleCumulativeFrequency),
        MaleFrequency = x.Sum(y => y.Gender.MaleFrequency)
    }
}).ToList();

Что делает следующее:

  1. Объединяет списки, создавая IEnumerable<Name>, который содержит содержимое обоих списков.
  2. Группирует списки по свойству NameText, поэтому, если есть одинаковые имена с одинаковым NameText, они будут отображаться в одной группе.
  3. Выбирает набор новых объектов Name с суммированием свойств каждого сгруппированного имени ... вы также можете использовать Среднее, если это имеет больше смысла.
  4. Преобразует весь запрос в List<Name>, вызывая метод ToList ().

Изменить: Или, как вы сказали ниже, вы просто хотите объединить два списка ... сделать это:

List<Name> allNames = femaleNames.Union(maleNames).ToList();
2 голосов
/ 16 марта 2010

Это очень похоже на данные о частоте переписных названий, верно? Пол является немного неправильным для вашего класса, это больше похоже на "FrequencyData".

Фактически вам нужен словарь, чтобы вы могли найти любое имя и получить для него четыре значения. Вы можете просто взять мужчин и сделать ToDictionary (...) для него, а затем перебрать женщин, если имя существует в словаре, заменить женские вероятности на нем, если его нет, создать новую запись словаря .

Мой собственный подход к этим же данным заключался в создании таблицы в базе данных со всеми четырьмя присоединенными значениями.

Вот код для вашего сценария ...

    Dictionary<string, Gender> result;

    result = males.ToDictionary(x => x.NameText, x => x.Gender);
    foreach (var female in females)
    {
        if (result.ContainsKey(female.NameText))
        {
            result[female.NameText].FemaleCumulativeFrequency = female.Gender.FemaleCumulativeFrequency;
            result[female.NameText].FemaleFrequency = female.Gender.FemaleFrequency;
        }
        else
            result.Add(female.NameText, female.Gender);
    }
1 голос
/ 16 марта 2010

Я думаю, что это может быть то, что вы хотите, хотя я не уверен, что он обрабатывает кумулятивные частоты, как вы ожидаете:

var mergedNameList = maleNames
    .Concat(femaleNames)
    .GroupBy(n => n.NameText)
    .Select(nameGroup => new Name
    {
        NameText = nameGroup.Key,
        Gender = new Gender
        {
            MaleFrequency = nameGroup.Sum(n => n.Gender.MaleFrequency),
            MaleCumulativeFrequency = nameGroup.Sum(n => n.Gender.MaleCumulativeFrequency),
            FemaleFrequency = nameGroup.Sum(n => n.Gender.FemaleFrequency),
            FemaleCumulativeFrequency = nameGroup.Sum(n => n.Gender.FemaleCumulativeFrequency)
        }
    }.ToList();
...