Search code examples
c#asp.netdynamicpetapoco

Remove duplicate items from a List<String[]> in C#


I have an issue here a bit complex than I'm trying to resolve since some days ago. I'm using the PetaPoco ORM and didn't found any other way to do a complex query like this:

   var data = new List<string[]>();
   var db = new Database(connectionString);
   var memberCapabilities = db.Fetch<dynamic>(Sql.Builder
       .Select(@"c.column_name
           ,CASE WHEN c.is_only_view = 1
               THEN c.is_only_view
               ELSE mc.is_only_view end as is_only_view")
       .From("capabilities c")
       .Append("JOIN members_capabilities mc ON c.capability_id = mc.capability_id")
       .Where("mc.member_id = @0", memberID)
       .Where("c.table_id = @0", tableID));

   var roleCapabilities = db.Fetch<dynamic>(Sql.Builder
       .Select(@"c.column_name
           ,CASE WHEN c.is_only_view = 1
               THEN c.is_only_view
               ELSE rc.is_only_view end as is_only_view")
       .From("capabilities c")
       .Append("JOIN roles_capabilities rc ON c.capability_id = rc.capability_id")
       .Append("JOIN members_roles mr ON rc.role_id = mr.role_id")
       .Where("mr.member_id = @0", memberID)
       .Where("c.table_id = @0", tableID));

I'm trying to get the user capabilities, but my system have actually to ways to assign an user a capability, or direct to that user or attaching the user to a role. I wanted to get this merged list using a stored procedure but I needed cursors and I thought maybe should be easier and faster doing this on the web application. So I get that two dynamics and the members capabilities have priority to the roles capabilities, so I need to check if that using loops. And I did like this:

   for (int i = 0; i < roleCapabilities.Count; i++)
   {
       bool added = false;
       for (int j = 0; j < memberCapabilities.Count; j++)
           if (roleCapabilities[i].column_name == memberCapabilities[j].column_name)
           {
               data.Add(new string[2] { memberCapabilities[j].column_name, Convert.ToString(memberCapabilities[j].is_only_view) });
               added = true;
               break;
           }
       if (!added)
           data.Add(new string[2] { roleCapabilities[i].column_name, Convert.ToString(roleCapabilities[i].is_only_view) });
        }

So now the plan is delete the duplicate entries. I have try using the following methods with no results:

  data = data.Distinct();

Any help? Thanks


Solution

  • If I understand your question correctly you want to get a distinct set of arrays of strings, so if the same array exists twice, you only want one of them? The following code will return arrays one and three while two is removed as it is the same as one.

    var one = new[] {"One", "Two"};
    var two = new[] {"One", "Two"};
    var three = new[] {"One", "Three"};
    
    List<string[]> list = new List<string[]>(){one, two, three};
    
    
    var i = list.Select(l => new {Key = String.Join("|", l), Values = l})
        .GroupBy(l => l.Key)
        .Select(l => l.First().Values)
        .ToArray();