dotnet-practitioner
dotnet-practitioner

Reputation: 14148

replace 3 levels of nested for loops by efficient code possibly linq

Is there a way of replacing following 3 levels of nested for-loops into more efficient or cleaner code? Would linq be able to make it more efficient and easy to read?

Please help. Thanks

bool myMatch = false;

foreach (MyEntityClass entitySmallerSet in entitiesSmallerSet)
{
    if (entityLargerSet.Key.Equals(entitySmallerSet.Key))
    {
        foreach (var stringResValLarge in entityLargerSet.StringResourceValues)
        {
            foreach (var stringResValSmall in entitySmallerSet.StringResourceValues)
            {
                if (stringResValSmall.Culture.Equals(stringResValLarge.Culture)
                    && stringResValSmall.Value.Equals(stringResValLarge.Value))
                {
                    myMatch = true;
                }
            }
        }
    }
}

Upvotes: 1

Views: 859

Answers (3)

Forty-Two
Forty-Two

Reputation: 7605

Resharper does this with it:

    bool myMatch = false;
    foreach ( var stringResValLarge in 
    from entitySmallerSet 
    in entitiesSmallerSet.Where(entitySmallerSet => entityLargerSet.Key.Equals( entitySmallerSet.Key )) 
    from stringResValLarge in entityLargerSet 
    from stringResValSmall in entitySmallerSet 
    where stringResValSmall.Equals( stringResValLarge )&& stringResValSmall.Equals( stringResValLarge ) 
    select stringResValLarge )
    {
      myMatch = true;
    }

(had to remove some of the dot props to get resharper to do it's thing. )

Upvotes: 0

Lee
Lee

Reputation: 144136

bool myMatch = entitiesSmallerSet
    .Where(e => entityLargerSet.Key.Equal(e.Key))
    .SelectMany(e => e.StringResourceValues)
    .Join(entityLargerSet.StringResourceValues, small => new { Culture = small.Culture, Value = small.Value }, large => new { Culture = large.Culture, Value = large.Value }, (s, l) => new object())
    .Any();

Instead of the join you can use Intersect:

bool myMatch = entitiesSmallerSet
    .Where(e => entityLargerSet.Key.Equal(e.Key))
    .SelectMany(e => e.StringResourceValues)
    .Select(e => new { Culture = e.Culture, Value = e.Value })
    .Intersect(entityLargerSet.StringResourceValues.Select(l => new { Culture = l.Culture, Value = l.Value }))
    .Any();

Upvotes: 9

Eugene Y.
Eugene Y.

Reputation: 306

You can use this idea (pseudocode):

var myMatch = (from se in entitiesSmallerSet
               where e.Key.Equals(entitySmallerSet.Key)
               from seVal in se.StringResourceValues
               from leVal in entityLargerSet.StringResourceValues
               where seVal.Culture.Equals(leVal.Culture)
                  && leVal.Value.Equals(leVal.Value)
               select seVal).Any();

Upvotes: 0

Related Questions