# Set part/range of list to specific value

I have a list of tuples like so:

{{24, 29}, {155, 161}, {185, 193}, {220, 224}, {229, 234}, {251,
256}, {290, 297}, {394, 406}, {568, 586}, {648, 654}, {691,
696}, {760, 772}, {852, 856}, {860, 864}, {923, 929}, {954,
958}, {984, 992}, {1099, 1108}, {1138, 1144}, {1179, 1185}}


that correspond to intervals on the number line from 1 to 1199. Given this list of tuples I want to construct an array of zeros and ones such that the array takes on the value 1 only between the intervals (ends points included). I have spent the better part of an hour trying to figure this out without any success.

My solution was along the lines of:

ArrSet[ints_] :=
Module[{x = ConstantArray[0, 1199]}, (Scan[
x[[#[] ;; #[]]] = 1 &, ints]; x)]


but I can't get it to work. What am I doing wrong?

For context the list of intervals is a value in an association and once I have a working ArrSet the intention is to modify it to ArrSet[key_, ints_] and do a KeyValueMap on the association so that each key/value pair has its on one-zero array.

• You can e.g. define a function pred, that gives 1 or 0 ,depending on the argument being a member of an interval or not. E.g: dat = {{24, 29}, {155, 161}, {185, 193}, {220, 224}, {229, 234}, {251, 256}, {290, 297}, {394, 406}, {568, 586}, {648, 654}, {691, 696}, {760, 772}, {852, 856}, {860, 864}, {923, 929}, {954, 958}, {984, 992}, {1099, 1108}, {1138, 1144}, {1179, 1185}}; pred[x_] = AnyTrue[dat, (#[] <= x <= #[]) & ]; pred /@ Range – Daniel Huber Oct 22 at 14:31
• @DanielHuber That might be a workable solution ... going to try that approach. Do you know what is wrong/breaking in the question's code? That seemed more direct/cleaner but just won't work. – ITA Oct 22 at 14:39
• Yor codes does not work because "&" (function) has a low precedence. If you use brackets it will work: ArrSet[ints_] := Module[{x = ConstantArray[0, 1199]}, (Scan[(x[[#[] ;; #[]]] = 1) &, ints]; x)] – Daniel Huber Oct 22 at 15:18
• I would have never figured that on my own ... 😅. – ITA Oct 22 at 15:27
• Pay attention to the color of the slots (#). In your code, the slots are pink-ish and they should be green. – Sjoerd Smit Oct 22 at 15:52

tuples = {{24, 29}, {155, 161}, {185, 193}, {220, 224}, {229,
234}, {251, 256}, {290, 297}, {394, 406}, {568, 586}, {648,
654}, {691, 696}, {760, 772}, {852, 856}, {860, 864}, {923,
929}, {954, 958}, {984, 992}, {1099, 1108}, {1138, 1144}, {1179,
1185}};

sa = SparseArray[Thread[Join @@ Range @@@ tuples -> 1], {1199}] Normal @ sa You can also do:

m1 = ConstantArray[0, 1199];
m1[[Join @@ Range @@@ tuples]] = 1;
m1 == Normal @ sa

True

m2 = MapAt[1 &, ConstantArray[0, 1199], List /@ (Span @@@ tuples)];
m2 == Normal @ sa

True

m3 = ConstantArray[0, 1199];
Do[m3[[Span @@ t]] = 1, {t, tuples}]
m3 == Normal @ sa

True

m4 = ReplacePart[ConstantArray[0, 1199],
Alternatives @@ Join @@ Range @@@ tuples -> 1];

m4 == Normal @ sa

True

• I am trying to avoid saying "Thanks" so let me say: This answer is very detailed and adds more than one way to solve things (when it didn't have to). The MapAt solution and ReplacePart solution are closer to my way of thinking and it is good to know they exist and that there is so much to learn about this language! – ITA Oct 23 at 0:26