6
\$\begingroup\$

Can you find a more understandable way to write the following one-liner?

Enumerable.Range(0, relation.Fields.Count).
           Any(i => relation.Fields[i] != relation.ForeignFields[i])

but still preserving its brevity?

Simply put, I wanna cycle on relation.Fields collection to see if their string elements are one-by-one equal to relation.ForeignFields ones.

The reason I had to use Enumerable.Range is that I need an index, in order to cycle the two collections.

Note: they have for sure the same count.


I wrote an extension method based on @t3chb0t's answer

\$\endgroup\$
6
  • 1
    \$\begingroup\$ I have rolled back the last edit. Please see what you may and may not do after receiving answers. \$\endgroup\$ Commented Jul 22, 2016 at 15:57
  • \$\begingroup\$ @Pimgd In spite of my little reputation on CodeReview, I have plenty on StackOverflow and I know how to behave on StackExchange. \$\endgroup\$ Commented Jul 22, 2016 at 15:59
  • \$\begingroup\$ @Pimgd The fact is that my edit was not a complete answer, so I didn't post it as a self-answer, but accepted t3chb0t's one instead. \$\endgroup\$ Commented Jul 22, 2016 at 16:00
  • 2
    \$\begingroup\$ That's great. We have slightly different rules here, please read them. What you did was not so much wrong as that it risks reviewers reviewing your newly added code, which creates a problematic cycle as some answers refer to revision 1 and others to revision 2. Thus we rollback - not because it is wrong to want to say what you did, but to prevent reviewers from wasting their time. \$\endgroup\$ Commented Jul 22, 2016 at 16:00
  • 2
    \$\begingroup\$ one option would be post a self answer (with reasoning included, not just a code dump), link to it in the question, leave the accept as is \$\endgroup\$ Commented Jul 22, 2016 at 16:04

3 Answers 3

7
\$\begingroup\$

This is not realy shorter then your example but it will work with any enumerable and does not require a count/length to be known:

var any = Fields
    .Select((field, i) => new { filed, i })
    .Any(x => x.field != relation.ForeignFields[x.i])

I think this might work as well if both collections are in sync:

var any = Fields.Zip(relation.ForeignFields, (x, y) => x != y).Any(z => z);
\$\endgroup\$
13
  • 1
    \$\begingroup\$ Unfortunately, AFAIK, Any does not support index as second lambda parameter, only Select does. \$\endgroup\$ Commented Jul 22, 2016 at 15:19
  • \$\begingroup\$ Ok, now that you've edited the answer, it's ok. \$\endgroup\$ Commented Jul 22, 2016 at 15:21
  • \$\begingroup\$ @Teejay I thought it would so I checked it and fixed the example. \$\endgroup\$ Commented Jul 22, 2016 at 15:21
  • \$\begingroup\$ @Teejay I noticed it at the same time as you've commented ;-) \$\endgroup\$ Commented Jul 22, 2016 at 15:21
  • \$\begingroup\$ Ok, anyway I was looking for something even easier, but probably you're right when saying that "this is the shortest"... \$\endgroup\$ Commented Jul 22, 2016 at 15:23
9
\$\begingroup\$

Can you not simply do SequenceEqual?

var list = new List<string> { "test1", "test2", "test3" };
var list2 = new List<string> { "test1", "test2", "test3" };

var areListsEqual = list.SequenceEqual(list2);
\$\endgroup\$
7
  • 1
    \$\begingroup\$ @Hosch250 it (code by asker) seems to check if any not matches - so if all match. \$\endgroup\$ Commented Jul 22, 2016 at 16:13
  • \$\begingroup\$ Thanks, dindn't know about this one. I'll use it for the particular case. This wouldn't be applicable if the lambda condition was different though, so my accepted answer will remain the current one. Anyway, I upvoted. \$\endgroup\$ Commented Jul 22, 2016 at 16:14
  • \$\begingroup\$ Ah, right. Removed my comment. \$\endgroup\$ Commented Jul 22, 2016 at 16:15
  • \$\begingroup\$ If you wanted to play with the elements afterward, you can also do list.Except(list2) or vice versa. \$\endgroup\$ Commented Jul 22, 2016 at 16:17
  • \$\begingroup\$ This also has a different meaning than the example in @Teejay's question. The original code checks whether Fields is a prefix of ForeignFields, not whether they're equal. \$\endgroup\$ Commented Jul 22, 2016 at 20:25
3
\$\begingroup\$

Based on @t3chb0t's answer, I ended up writing an extension method Any that also provides indexing:

public static bool Any<T>(this IEnumerable<T> enumerable, Func<T, int, bool> lambda)
{
    return enumerable.Select((el, ix) => new { el, ix }).Any(x => lambda(x.el, x.ix));
}

Use:

relation.Fields.Any((f, ix) => f != relation.ForeignFields(ix))

That way, code in the main software remains concise and understandable.


I wrote an All version as well:

public static bool All<T>(this IEnumerable<T> enumerable, Func<T, int, bool> lambda)
{
    return enumerable.Select((el, ix) => new { el, ix }).All(x => lambda(x.el, x.ix));
}
\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.