0

In the example below, I have two sets of objects that have matching keys.

class Stuff
{
    int Key1 { get; set; }
    ... other props
}

class OtherStuff
{
    int Key2 { get; set; }
    ... other props
}

I would like to join two lists of these objects together as one list of pairs. Assume there is a class called Error that represents the error state. I tried to do it in the following way;

Either<Error, List<Stuff>> eitherStuff = GetStuff();

Either<Error, List<OtherStuff>> eitherOtherStuff = GetOtherStuff();

Either<Error, List<object>> eitherCombined =
    from stuff in eitherStuff
    select stuff into s1
    from otherStuff in eitherOtherStuff
    select otherStuff into s2
    from s1item in s1
    join s2item in s2
    on s1item.Key1 equals s2item.Key2
    select new {s1item, s2item};

But this fails with

The name 's1' does not exist in the current context.

What is the best way to combine two Either<Error, List<T>>?

MeanGreen
  • 3,098
  • 5
  • 37
  • 63
Steztric
  • 2,832
  • 2
  • 24
  • 43

1 Answers1

2
Either<Error, List<(Stuff, OtherStuff)>> eitherCombined =
                from stuff in eitherStuff
                from otherStuff in eitherOtherStuff
                select (from s1item in stuff
                        join s2item in otherStuff
                        on s1item.Key1 equals s2item.Key2
                        select (s1item, s2item)).ToList();

The outer LINQ expression combines both Either elements. The inner LINQ expressions joins lists (if both Either are "right").

I changed your return type to tuple to avoid object. Your original example would be like

Either<Error, List<object>> eitherCombined =
                from stuff in eitherStuff
                from otherStuff in eitherOtherStuff
                select (from s1item in stuff
                        join s2item in otherStuff
                        on s1item.Key1 equals s2item.Key2
                        select new {s1item, s2item} as object).ToList();

You could use your anonymous type (without unsafe object) like this:

var eitherCombined =
                from stuff in eitherStuff
                from otherStuff in eitherOtherStuff
                select (from s1item in stuff
                        join s2item in otherStuff
                        on s1item.Key1 equals s2item.Key2
                        select new {s1item, s2item}).ToList();

Another hint: you could use one of LanguageExt immutable types instead of List...

stb
  • 772
  • 5
  • 15