1

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;
                }
            }
        }
    }
}
6
  • Where is the definition for entityLargerSet? Commented Oct 16, 2012 at 20:56
  • No formatting, no context, just garbage... Commented Oct 16, 2012 at 20:57
  • Are we solving your homeworks? :p Commented Oct 16, 2012 at 20:58
  • this is related to my work.. I have been asked to make it more efficient but I don't know how to. Commented Oct 16, 2012 at 20:59
  • Nested looping over sets looks to me as if you could achieve better runtime performance by keeping your data in different data structures. A Dictionary<Tuple<Culture, T>, IEnumerable<MyEntityClass>> for each entity for instance, where T is the type of Value. What do you think (it's just an idea)? Commented Oct 16, 2012 at 21:03

3 Answers 3

9
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();
Sign up to request clarification or add additional context in comments.

2 Comments

+1 for this as it is very elegant, plus it breaks as soon as one match is found. The original solution loops over and over again, even when match has been true for long.
Lee, thanks for the answer.. how would I identify the entityLargerSet which is missing from the entitiesSmallerSet?
0

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();

Comments

0

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. )

3 Comments

@Eonasdan I am not supposed to format the answer/question to make it more readible. If someone asks/answers, he/she should show his/her best effort to format it.
@L.B I wasn't suggesting that you should. My comment was meant to indicate I was surprised someone would down vote just for formatting, until I scrolled the answer. I, however, would have simply edited it.
@Eonasdan Why should I edit it? Just to make other one's work?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.