-1

This is a very easy problem that I have been stuck on.

I have a IEnumerable IGrouping object with grouped up common key items in it. I now need to compare each of the same common key item in the IEnumerable IGrouping object itself. I used 2 foreach loop to achieve that but the problem is the foreach causes repetition. I need to loop and compare each item without repetition of the one which already went through.

Parallel.ForEach((sameQuickHashGroups, quickHashGroup) =>
{
    foreach (var groupFile in quickHashGroup)
    {
        foreach (var groupFile2 in quickHashGroup)
        {                               
            if (HashTool.ByteToByteCompare(groupFile.FileName, groupFile2.FileName))
            {
                groupFile.FullHash = count.ToString();
                groupFile2.FullHash = count.ToString();
            }                                                           
         }
         count;
     }
});

Can anyone solve this?

L. Guthardt
  • 1,990
  • 6
  • 22
  • 44
user2672399
  • 185
  • 1
  • 10
  • `quickHashGroup` is pure `IEnumerable`, or maybe array or list? – Evk Nov 21 '17 at 10:36
  • @Evk it is pure IEnumerable. – user2672399 Nov 21 '17 at 10:37
  • 3
    Please post a *complete*, concise sample that demonstrates the issue. https://stackoverflow.com/help/how-to-ask – jeroenh Nov 21 '17 at 10:40
  • 1
    What @jeroenh is asking for is a [mcve] – Jamiec Nov 21 '17 at 10:41
  • 1
    I also doubt the code you have here - None of the [overloads of `Parallel.ForEach`](https://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.foreach(v=vs.110).aspx) take arguments which looks like yours. The first argument is usually the enumerable and the second is the action to take. – Jamiec Nov 21 '17 at 10:53
  • When the `FileName`s are strings, why use a HashTool to compare them? What's wrong with `==` ? – H H Nov 21 '17 at 11:32

1 Answers1

0

Assuming I understand the question now (as apposed to my first answer), You are basically asking how to compare each pair of elements only once.

I would use Linq's ToList() on the IEnumerable, and then use for loops instead of foreach loops.
This way you can compare each pair of elements only once:

var quickHashGroupList = quickHashGroup.ToList();
for(var i = 0; i < quickHashGroupList.Count-1; i++)
{
    var groupFile = quickHashGroupList[i];
    for(var j = i+1; j < quickHashGroupList.Count; j++)
    {
        var groupFile2 = quickHashGroupList[j];
        if (HashTool.ByteToByteCompare(groupFile.FileName, groupFile2.FileName))
        {
            groupFile.FullHash = count.ToString();
            groupFile2.FullHash = count.ToString();
        }     
    }
}

Note that the first loop goes only to count-2, since the second loop starts at i+1.

Zohar Peled
  • 79,642
  • 10
  • 69
  • 121
  • That will not remove all duplicate comparisions. Suppose list is [1,2]. It will compare 1 with 1 (removed by your check), 1 with 2, 2 with 1 (duplication), and 2 with 2 (removed by your check). – Evk Nov 21 '17 at 11:33
  • I thought that's what the OP wanted, but I might have misunderstood the question. Give me a minute to read it again. – Zohar Peled Nov 21 '17 at 11:36
  • Well in any case you don't need indexes for what you did, you can just compare `groupFile != groupFile2` because it's the same object. – Evk Nov 21 '17 at 11:38
  • @Evk seems like I did misunderstood the question. Editing my answer. – Zohar Peled Nov 21 '17 at 11:44