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\$ – Pimgd Jul 22 '16 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\$ – Teejay Jul 22 '16 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\$ – Teejay Jul 22 '16 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\$ – Pimgd Jul 22 '16 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\$ – Pimgd Jul 22 '16 at 16:04
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\$ – Teejay Jul 22 '16 at 15:19
  • \$\begingroup\$ Ok, now that you've edited the answer, it's ok. \$\endgroup\$ – Teejay Jul 22 '16 at 15:21
  • \$\begingroup\$ @Teejay I thought it would so I checked it and fixed the example. \$\endgroup\$ – t3chb0t Jul 22 '16 at 15:21
  • \$\begingroup\$ @Teejay I noticed it at the same time as you've commented ;-) \$\endgroup\$ – t3chb0t Jul 22 '16 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\$ – Teejay Jul 22 '16 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\$ – Pimgd Jul 22 '16 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\$ – Teejay Jul 22 '16 at 16:14
  • \$\begingroup\$ Ah, right. Removed my comment. \$\endgroup\$ – user34073 Jul 22 '16 at 16:15
  • \$\begingroup\$ If you wanted to play with the elements afterward, you can also do list.Except(list2) or vice versa. \$\endgroup\$ – Nick Spicer Jul 22 '16 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\$ – Alex Reinking Jul 22 '16 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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.