Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get moving combination from two List<String> in C#?

Tags:

c#

lambda

linq

I'm having two List<String> which contains

ListOne
          A
          B
          C
ListTwo
          A
          B
          C
          D

Now i need to get the moving combinations to a list string

So the output list will contain

         A-B
         A-C
         A-D
         B-C
         B-D
         C-D

Now i'm using Nested for loop for this.? Is there any way to do this using LINQ or LAMBDA EXPRESSION Please help me to do this. Thanks in advance

Sample Code

List<String> ListOne = new List<string> { "A","B","C"};
List<String> ListTwo = new List<string> { "A", "B", "C", "D" };

List<String> Result = new List<string>(from X in ListOne 
                                       from Y in ListTwo 
                                       where X!=Y
                                        select string.Format("{0}-{1}", X, Y));

But its not giving the correct output

  It produces like

            A-B
            A-C
            A-D
            B-A
            B-C
            B-D
            C-A
            C-B
            C-D

But the required output is like

         A-B
         A-C
         A-D
         B-C
         B-D
         C-D

Sample Code using For Loop

List<String> ResultTwo = new List<string>();
        for (int i = 0; i < ListOne.Count; i++)
        {
            for (int j = 0; j < ListTwo.Count; j++)
            {
                if(ListOne[i] != ListTwo[j])
                    if (ResultTwo.Contains(ListOne[i] + "-" + ListTwo[j]) == false && ResultTwo.Contains(ListTwo[j] + "-" + ListOne[i]) == false) 
                ResultTwo.Add(ListOne[i] + "-" + ListTwo[j]);
            }
        }

its working fine.... but i just need a simple way ( Using LINQ)

like image 953
Thorin Oakenshield Avatar asked Dec 17 '10 12:12

Thorin Oakenshield


3 Answers

Following your edits this should do the trick:

List<string> ListOne = new List<string>(){"A","B","C"};
List<string> ListTwo = new List<string>(){ "A","B","C","D"};

var result = from a in ListOne
             from b in ListTwo
             let condition = a.CompareTo(b)
             where condition != 0
             select condition < 0 ? a + "-" + b : b + "-" + a;


foreach (var v in result.Distinct())
{
    Console.WriteLine(v);
}

The second version that preserves order (ItemFromList1 - ItemFromList2):

        var result =
            from o in
                (
                    from a in ListOne
                    from b in ListTwo
                    let condition = a.CompareTo(b)
                    where condition != 0
                    select new { a, b, condition }
                )
                group o by
                    o.condition < 0 ? o.a + "-" + o.b : o.b + "-" + o.a into g
                select g.Select(n => n.a + "-" + n.b).Take(1).ToArray()[0];
like image 69
nan Avatar answered Sep 23 '22 06:09

nan


So you want all matches except

  • item matched to itself
  • item matched to smaller item

and no duplicates.

Here it is:

IEnumerable<string> result = 
  (
    from a in ListOne
    from b in ListTwo
    where a != b
    select a.CompareTo(b) < 0 ? a + "-" + b : b + "-" + a
  ).Distinct();

Stating the requirement is 90% of the battle.


If you NEED the first item in the pairing to come from the first list, this will do it:

IEnumerable<string> result = 
  (
    from a in ListOne
    from b in ListTwo
    select new
    {
      A = a,
      B = b,
      Combo = a.CompareTo(b) < 0 ? a + "-" + b : b + "-" + a
    } into x
    group x by x.Combo into g
    select g.Select(x2 => x2.A + "-" + x2.B).First()
  )
like image 35
Amy B Avatar answered Sep 23 '22 06:09

Amy B


var listA = new List<string> { "A", "B", "C" };
var listB = new List<string> { "A", "B" };
var result = listA.SelectMany((a, indexA) =>
                     listB.Where((b, indexB) => 
                            listB.Contains(a) ? !b.Equals(a)&&indexB > indexA 
                                              : !b.Equals(a))
                          .Select(b => string.Format("{0}-{1}", a, b)));
like image 42
Cheng Chen Avatar answered Sep 23 '22 06:09

Cheng Chen