9

I have a list in c# as:

List<Data> uData = new List<uData>();

Where uData is populated from UI as:

{
   Id: 1,
   Name: "Smith",
   Input: "7,8",
   Output: "Output1",
   CreatedBy: "swallac",
   CreatedON: "12/01/2018"
},
{
   Id: 2,
   Name: "Austin",
   Input: "9,10",
   Output: "Output1",
   CreatedBy: "amanda",
   CreatedON: "12/03/2018"
},
{
   Id: 3,
   Name: "Smith",
   Input: "22,22",
   Output: "Output2",
   CreatedBy: "swallac",
   CreatedON: "12/01/2018"
},
{
   Id: 4,
   Name: "Smith",
   Input: "9,8",
   Output: "Output2",
   CreatedBy: "aaa",
   CreatedON: "12/01/2018"
},
{
   Id: 5,
   Name: "Peter",
   Input: "7,8",
   Output: "Output3",
   CreatedBy: "swallac",
   CreatedON: "12/02/2018"
}

What I want to do is search this list on "Output" key, and find out if there are in duplicates in the corresponding combination value of "Input" & CreatedBy key.

For example, in my above example list I have three Output: Output1,Output2, Output3. Now for lists with key of Output value as "Output1" & "Output3" the corresponding "Input" & "CreatedBy" key value is duplicate here. The value being "7,8"& "swallac" as combined value. This is what I want to highlight

For this I tried out the below query:

var myList = uData.GroupBy(l => l.Ouput)
                  .SelectMany(g => g.GroupBy(x => (x.Input, x.CreatedBy)).Where(x => x.Count() > 1))
                  .SelectMany(x => x);

This does not gives me any error but does not gives me desired result as it lists all the data. What am I missing here.

--Updated---

Earlier I wanted that the Input should not be repeated in one Output because of which I had the below query.

uData.GroupBy(l => l.Ouput)
    .Any(g => g.GroupBy(x => x.Input).Any(x => x.Count() > 1))

Now I want another query to check if the combination of Input and CreatedBy is repeated in the list.

I tried the above posted query and below query as per the suggestion:

uData.GroupBy(g=> new {g.CreatedBy,g.Input})
    .Where(w=>w.Count() > 1)

But this returns me all the list instead of the duplicate

Updated to add an example link:

https://dotnetfiddle.net/HWMYp6

I have created the example in above link.

In the example I want to mark the set with id 10 with output (output5) as the duplicate as such combination of Input and created by already existed before in id 1,2,3 (all of which belong to output1). So basically one combination of input and createby should not be repeated over another set. The reference key being Output. Sorry if my initial post was not very clear. I tried.

4
  • 1
    Just for clarification, so currently your query is saying "return me all the objects that happen to have the same Output, Input and CreatedBy" ? in other words uData.GroupBy(l =>new { l.Ouput,l.Input, l.CreatedBy }) correct? if this is the case then the result sequence should be empty as there are no objects that happen to have the same Output, Input and CreatedBy in the data you've shown? I'm I missing something here? Commented Dec 13, 2018 at 14:56
  • as for "Now I want another query to check if the combination of Input and CreatedBy is repeated in the list." that would just be var myList1 = uData.GroupBy(x => (x.Input, x.CreatedBy)) .Any(x => x.Count() > 1); or uData.GroupBy(g=> new {g.CreatedBy,g.Input}).Any(x => x.Count() > 1);. if you're still not getting the desired results please consider stating what you want as a result and why? the more information with examples the better. Commented Dec 13, 2018 at 16:51
  • Let me spend some time analyzing this. Will get back. Commented Dec 13, 2018 at 17:11
  • @Aomine Please see my updated post with example. Commented Dec 13, 2018 at 19:03

3 Answers 3

5

it seems like you want to group by the "created by" and "input" only in which case a slight modification to your current query should suffice:

var result = uData.GroupBy(x => (x.Input, x.CreatedBy))
                  .Where(x => x.Count() > 1)
                  .SelectMany(x => x);

I've simply removed the GroupBy for the Output field.

  • GroupBy reads as "group by Input and CreatedBy"
  • Where reads as "retain the groups where there are two or more items"
  • SelectMany collapse the nested sequences into a IEnumerable<Data>

Update:

Given your edit, you're looking for:

var myList = uData.GroupBy(x => new {x.Input, x.CreatedBy})
                  .SelectMany(x => x.GroupBy(z => z.Output).Skip(1))
                  .SelectMany(x => x);
Sign up to request clarification or add additional context in comments.

4 Comments

Not sure what I am doing wrong or may be something issue with my logic here. I have updated my post. I just want that the combination of Input and Output should not be repeated for its value. What I think the issue could be because of comma in the column value because of which its not grouping correctly?
@karen FYI, if you're using this in production code, make sure you get some good amount of tests around it. I've only had 5-10 mins to look at your updated post and testing my solution against the examples you've given it seems to produce correct results.
Thanks this seems to be working with my initial tests. I will run few tests and update. Could you let me know why using Skip in the Linq above.
@karen the idea behind the solution is to find all the objects that have the same Input and CreatedBy hence the first GroupBy, the second GroupBy then does another grouping based on the Output. so at this point, we have all the objects that have the same Input, CreatedBy and Output in their respective groups but anything after the first group is a duplicate because they have different value for Output than the first group hence Skip(1).
1

You want to know for any Output if there is a matching Input & CreatedBy so you are grouping by Input & CreatedBy with just a count of the results being greater than 1.

var myList = uData.GroupBy(g=> new {g.CreatedBy,g.Input})
    .Where(w=>w.Count() > 1)

Comments

0

Your code does not run at all, but if I fix its syntax it seems to work like you intended.

var myList = uData.GroupBy(l => l.Output)
              .SelectMany(g => g.GroupBy(x => new {x.Input, x.CreatedBy}).Where(x => x.Count() > 1))
              .SelectMany(x => x);

Fiddle to show it (I modified the entries with Id=3 and Id=5 to create a duplicate): https://dotnetfiddle.net/r5mVKw

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.