GroupBy в LINQ и установить свойство - PullRequest
4 голосов
/ 27 сентября 2011

У меня есть такой класс:

public class Foo
{
  public string Regn{get;set;}

  public string DocName{get;set;}

  ...
}

В моем приложении этот класс использует IEnumerable:

IEnumerable<Foo> items;

Как получить новый IEnumerable, где для всех элементов с одинаковым свойством Regn и DocName свойство DocName устанавливается следующим образом (только если объекты с одинаковым DocName> 1):

item.DocName=item.DocName+".1";//+"2",etc.

[UPDATE] Пример ввода:

Regn DocName
1    1
1    2
1    2
2    5
2    5
2    6

Выход:

Regn DocName
1    1
1    2.1
1    2.2
2    5.1
2    5.2
2    6

Ответы [ 4 ]

2 голосов
/ 27 сентября 2011

Если у вас есть конструктор по умолчанию для Foo, попробуйте использовать это:

var newItems = items.
            GroupBy(f => Tuple.Create(f.Regn, f.DocName)).
            SelectMany(gr => gr.Count()<=1 ? gr : gr.Select((f, i) => new Foo
            {
                Regn = f.Regn,
                DocName = f.DocName + "." + (i + 1)
            }));
1 голос
/ 27 сентября 2011

Вы можете группировать с LINQ и разыгрывать группы, которые имеют только один элемент, а затем перебирать элементы в каждой группе, чтобы установить DocName:

// Group and filter
var groups = items.GroupBy(i => new { i.Regn, i.DocName })
                  .Where(g => g.Count() > 1);

// Iterate over each group with many items
foreach (var g in groups) {
    var itemsInGroup = g.ToArray();
    // Iterate over the items and set DocName
    for (var i = 0; i < itemsInGroup.Length; ++i) {
        itemsInGroup[i].DocName = g.Key + "." + (i + 1);
    }
}
0 голосов
/ 27 сентября 2011

Все в одном утверждении, просто для удовольствия.

var query = items.GroupBy(i => new { i.DocName, i.Regn })
    .SelectMany(group => 
        {
            int itemNum = 0;
            return group.Select(item =>
                {
                    var suffix = itemNum > 0 ? ("." + itemNum) : "";
                    var newDocName = item.DocName + suffix;
                    itemNum++;
                    return new { item, NewDocName = newDocName };
                });
        });
0 голосов
/ 27 сентября 2011

Или используйте оператор LINQ для создания нового результирующего набора, например:

var fixedSet = from entry in existing
               group entry by entry.DocName + entry.Regn into groupedEntries
               let groupedEntriesAsArray = groupedEntries.ToArray()
               from groupedEntry in groupedEntriesAsArray
               let index = Array.IndexOf(groupedEntriesAsArray, groupedEntry)
               select new Foo
               {
                   DocName =
                       string.Format("{0}.{1}", groupedEntry.DocName, index + 1),
                   Regn =
                       string.Format("{0}.{1}", groupedEntry.Regn, index + 1)
               };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...