4

I'm looking for an efficient way using linq.js to determine if a collection has more than one distinct value. I assume that the following approach is inefficient because it has to consider the entire collection.

if (Enumerable.From(collection).Distinct().Take(2).Count() > 1) {
    //it's not unique, continue loop
}

My question is similar to one: Efficient Linq Enumerable's 'Count() == 1' test

Is there a more efficient linq.js-based technique? Thanks!

Community
  • 1
  • 1
CalvinDale
  • 9,005
  • 5
  • 29
  • 38

2 Answers2

1

If you're specifically testing to see if a collection has more than one item in it, the idiomatic way to write it (IMHO) is to use Skip in conjunction with Any. Skip the first item and if there are any others in the collection, it has more than one. If it was empty, the Skip would effectively do nothing and there still wouldn't be any other items in the collection.

In your case, your condition would be:

if (Enumerable.From(collection).Distinct().Skip(1).Any()) {
    //it's not unique, continue loop
}
Jeff Mercado
  • 129,526
  • 32
  • 251
  • 272
0
var test = collection[0];
if (Enumerable
    .From(collection)
    .Skip(1)
    .Any(function (e) { return e != test; })
   )

Let me explain it. At least 2 distinct items mean that for any item there is at least one item that is not equal to it. Let's pick first item, you could pick any other, just first is more convenient and let's see if there is any other number not equal to it (except itself).

Andrey
  • 59,039
  • 12
  • 119
  • 163
  • I assume Andrey's approach here is a more efficient implementation. If one uses the Distinct operator as I did above or as in Jeff's technique below, the entire collection must be traversed to figure out what are the distinct values before the remainder of the linq expression can be applied. But that's the crux of my question. Is linq.js smart enough to figure out an efficient implementation based on whole expression? If so, the Distint() operator is more elegant. If not, the Skip.Any with a comparison predicate certainly will suffice. – CalvinDale Mar 28 '13 at 21:52
  • @CalvinDale it is efficient because it is O(n) in time and O(1) in memory, there is can hardly be better. – Andrey Mar 28 '13 at 22:23