Take the 2-minute tour ×

I have such class:

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

  public string DocName{get;set;}


In the my application this class uses with IEnumerable:

IEnumerable<Foo> items;

How to get new IEnumerable, where for all items with the same Regn and DocName property DocName sets like this(only if objects with same DocName >1):


[UPDATE] Input sample:

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
share|improve this question
I'm sorry but could you please clarify your question a little? I'm not sure what you'd like to achieve. Maybe add some pseudo code? –  Marc Sep 27 '11 at 6:45
@Dublicator, provide sample input and output for method. –  default locale Sep 27 '11 at 6:48
@MAKKAM, updated –  Dublicator Sep 27 '11 at 9:05
@Dublicator, I updated my answer. –  default locale Sep 27 '11 at 11:08
add comment

4 Answers

up vote 2 down vote accepted

If you have a default constructor for Foo try to use this:

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)
share|improve this answer
add comment

You can group with LINQ and cast out groups that only have one item, then iterate over the items in each group to set the 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);
share|improve this answer
add comment

All in one statement, just for fun.

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;
                    return new { item, NewDocName = newDocName };
share|improve this answer
add comment

Or use a LINQ statement to create a new result set like:

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)
share|improve this answer
any constructive argumentation for the downvote would be welcome.... –  Polity Sep 27 '11 at 7:09
I'm not a downvoter but some problems in your code: 1. Is not readable, 2. instead of Array.IndexOf(groupedEntriesAsArray, groupedEntry) you can use Select with indexer, your current approach is not good when performance issue is important also it's depend on equality implementation of class, may be cause same values for different objet. I think MAKKAM answer is best one in this case. –  Saeed Amiri Sep 27 '11 at 7:54
@Saeed Amiri: Thanks. I'm aware of the negative attributes using this approach, but i have to disagree on the readablity. I gave this example because no other answer introduced a query syntax like linq statement. The way i read it, it makes perfect sence and is the most readable (compared to others). But ofcourse this is a personal taste –  Polity Sep 27 '11 at 7:59
As you said it seems to be personal taste, but in all dot Notation prefered to query syntax in linq except in some cases see stackoverflow.com/questions/630045/… for discussion about this. –  Saeed Amiri Sep 27 '11 at 8:16
@Polity, your code is readable enough, but I totally agree with Saeed about performance issues. Also I think it's not a good idea to group by concatenation of Regn and DocName. Check out foo1 = new Foo{Regn="c", DocName="ab"} and foo2 = new Foo{Regn="bc", DocName="a"}. Your query will place both of them in one group. –  default locale Sep 27 '11 at 11:05
add comment

Your Answer


