# Check whether array has only constant entries?

I have an array arr with n entries. Now I want to check whether

arr[[1]]==arr[[2]]&&arr[[2]]==arr[[3]]&&...arr[[n-1]]==arr[[n]]


Of course I could use a for-loop, like

arr = {0, 1, 0, 0};
IsConst = True;
For[i = 1, i <= Length[arr], i++,
If[arr[[i]] != arr[[1]],
IsConst = False;
i = Length[arr];
];
];
Print[IsConst];


But that doesn't look too fast, so I wonder whether there is a faster way.

• Union or DeleteDuplicates and then if the resulting list has length greater than 1 then the elements are not all the same (not constant in your terminology) Jan 12, 2015 at 8:43

You can Apply (@@) Equal to your list:

constantQ = Equal@@#&;

constantQ @ {0,1,0,0}
(* False *)


or

constantQ2 = Max@#==Min@# &;
constantQ3 = Variance@#==0;
constantQ4 = Length@DeleteDuplicates@# == 1 &;


constantQ5 = SameQ @@ #&

Equal @@ {1, 1., 1}
(* True *)
SameQ @@ {1, 1., 1}
(* False *)


...

• That looks nice, very interesting solutions (I should, at some point, really understand that kind of instructions you show). Thanks! Jan 12, 2015 at 9:27
• @NicoDean, my pleasure..
– kglr
Jan 12, 2015 at 9:32

Not sure why people don't like DeleteDuplicates :)

Length@DeleteDuplicates@arr > 1


for me this is faster than other methods (using V9 OS X tonight)

If[Length[Tally[arr]] == 1, IsConst = True, IsConst = False]

• If is redundant here: IsConst = Length@Tally@arr == 1 Jan 12, 2015 at 9:37

Maybe the fastest is... just to compile the OP code

sameQ = Compile[{{arr, _Integer, 1}},
Module[{IsConst = True, i},
For[i = 1, i <= Length[arr], i++,
If[arr[[i]] != arr[[1]],
IsConst = False;
Break[];
]];
IsConst], CompilationTarget -> "C", "RuntimeOptions" -> "Speed"];

arr = ConstantArray[1, 10000000];
arr[[-1]] = 0;

sameQ[arr] // AbsoluteTiming
(* {0.027877, False} *)

constantQ4@arr // AbsoluteTiming (* fastest kguler's test *)
(* {0.062203, False} *)

• Oh wow. That's exactly why I love SE :D Jan 12, 2015 at 10:25
• One of these days I really should install a C compiler... Jan 12, 2015 at 10:57

This problem is in a manner an converse of How do you check if there are any equal arguments(even sublist) in a list? and is related to How do I check if any element in a list is positive? As with both of those there is a choice in approach of either scanning the entire light with a fast, vectorized operation, or providing for an early-exit behavior. Which one is desirable will depend on the most commonly tested expression form. Please review my answer to the second linked question for examples.

Using Tally or Max and Min are examples of methods that scan the entire list without the possibility of an early exist.

The length of the list can also affect the performance of the methods used. For example, as noted here UnsameQ works well on short lists (few arguments) but not on long ones. That doesn't appear to be the case with Equal and SameQ however so both of those are good general methods for your problem, and provide early exist behavior. You can choose between numeric and structural equivalence. kguler already showed these but repeated for completeness:

Equal @@ {1, 1, 1, 1}
SameQ @@ {1, 1, 1, 1}

True
True

Equal @@ {1, 1, 2, 1}
SameQ @@ {1, 1, 2, 1}

False
False

Equal @@ {1, 1, 1.0, 1}
SameQ @@ {1, 1, 1.0, 1}

True
False


To bring a unique method to this answer we can also use pattern matching for structural equivalence:

MatchQ[{1, 1, 1, 1}, {x_ ..}]
MatchQ[{1, 1, 2, 1}, {x_ ..}]

True

False


By naming the Pattern (x_) we restrict it to matching a particular expression. See:

• w.r.t. to timings, users should be reminded that Apply will unpack. Therefore MatchQ or checking the length of a deleted duplicates list may well be better options for packed arrays of larger length Jan 12, 2015 at 10:04
• @Mike Indeed. The issue of unpacking is mentioned in my answer to "How do I check if any element in a list is positive?" which I intend for people to read. I chose not to repeat myself here but instead direct readers to the earlier questions. Jan 12, 2015 at 10:10
• no worries. Am watching the cricket, having a beer, and reading this ...am not a multi tasker! Jan 12, 2015 at 10:13