7
$\begingroup$

Consider a list such as

s = {1, 2, 3, 3, 5, 6, 3}

With IntegerQ[number] , you know if number is an Integer, the result is True, and if not, the result is False.

But how could I do this without visiting each element as in Do[ ..., {i, 1, Length[...]}]?

$\endgroup$
4
  • $\begingroup$ @kuba, Yes I have viewed the documentation, but I can´t reach the solution. I know that was simple for people who know it. Not for me. $\endgroup$
    – Mika Ike
    Jun 7, 2014 at 15:25
  • 1
    $\begingroup$ I looked for a duplicate, but the closest I found was question 8650; in particular, this answer by Mr.Wizard uses VectorQ in the way my answer does. $\endgroup$
    – Michael E2
    Jun 7, 2014 at 19:07
  • $\begingroup$ I don't know how easily the best answer is found, but ArrayQ is used to test for a vector of integers here in documentation for IntegerQ, and one can find VectorQ here in the documentation for ArrayQ. $\endgroup$
    – Michael E2
    Jun 8, 2014 at 12:35
  • 1
    $\begingroup$ Somewhat related: 916, 7120, 16694 $\endgroup$
    – Michael E2
    Jun 8, 2014 at 12:36

3 Answers 3

12
$\begingroup$
s = {1,2,3,3,5,6,3};

I would write:

And @@ (IntegerQ /@ s)

EDIT

With V10 we can use:

AllTrue[s, IntegerQ]

True

NoneTrue[s // N, IntegerQ]

True

$\endgroup$
1
  • $\begingroup$ If you want to transcend an array (list of lists) and test each element in the array individually, specify a depth, e.g. for a 2D array try AllTrue[{{1, 0, 0}, {2, 0, a}}, NumericQ, 2]. $\endgroup$
    – Ghersic
    Jul 29, 2020 at 1:39
9
$\begingroup$

VectorQ is the best way I know. Here are three types of input, packed array of Integer, an (non-packed) array of Integer, and an array of not all Integer.

packed   = RandomInteger[10, 10^7];
unpacked = Flatten@ConstantArray[{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 10^6];
nonint   = ReplacePart[packed, 10^6 -> 1.5];

Developer`PackedArrayQ@unpacked
(* False *)

Testing VectorQ[list, IntegerQ]:

VectorQ[packed, IntegerQ]
VectorQ[unpacked, IntegerQ]
VectorQ[nonint, IntegerQ]
(*
  True
  True
  False
*)

Comparing the timings with two other methods (the timing function timeAvg is given below):

VectorQ[packed, IntegerQ] // timeAvg
VectorQ[unpacked, IntegerQ] // timeAvg
VectorQ[nonint, IntegerQ] // timeAvg
(*
  2.64695*10^-7
  0.0319406
  0.00318189
*)

MatchQ[packed, {___Integer}] // timeAvg
MatchQ[unpacked, {___Integer}] // timeAvg
MatchQ[nonint, {___Integer}] // timeAvg
(*
  9.5835*10^-7
  0.157701
  0.065558
*)

And @@ (IntegerQ /@ packed) // timeAvg
And @@ (IntegerQ /@ unpacked) // timeAvg
And @@ (IntegerQ /@ nonint) // timeAvg
(*
  2.782322
  2.858287
  2.540433
*)

You may note that on packed arrays VectorQ and MatchQ take virtually no time. In fact, it's the same amount of time no matter what the size. This is because a packed array is a special efficient internal representation of an array. In particular it has to be an array of all the same type of number (only Integer, Real, and Complex are allowed). So checking the type is easy. See What is a Mathematica packed array?


The site-standard timeAvg function:

SetAttributes[timeAvg, HoldFirst]
timeAvg[func_] := 
  Do[If[# > 0.3, Return[#/5^i]] & @@ 
    AbsoluteTiming@Do[func, {5^i}], {i, 0, 15}];
$\endgroup$
3
  • $\begingroup$ My function seems to unpack, whereas yours circumvents this nasty habit. Thanks, very instructive. $\endgroup$
    – eldo
    Jun 7, 2014 at 19:35
  • $\begingroup$ @eldo Thanks. I think the OP's use-case is unlikely to have a packed list, since it seems possible that not all entries are integers. (Indeed, it must be rare that one would need to do such a test on a packed array.) It appears that mapping IntegerQ over the list is the rate-limiting step. $\endgroup$
    – Michael E2
    Jun 7, 2014 at 19:55
  • $\begingroup$ I too like VectorQ to prevent unpacking. +1 $\endgroup$
    – Mr.Wizard
    Jun 8, 2014 at 13:32
2
$\begingroup$

Use Map, abbreviated /@. For example:

  lis = {4, 5/2, 3., 6/3, Pi};
  IntegerQ /@ lis               (* or Map[IntegerQ, lis] *)

(* {True, False, False, True, False} *)

$\endgroup$

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