0
$\begingroup$

I have an array with either 1 or 0. From this, I am trying to create a new array with intervals.

I have some base interval, one step, we can say 1 second here. If there is 0, I skip, if there is 1 I create an interval based on a position, which means if 1 is in the first place of the input array, I'll create interval {1, 2} and then if the next one is also 1, I'll change the first interval to {1,3}.

I wrote this code that works, but I am trying to figure out a better way using functional methods like Fold/MapIndexed/Select to get the final array but it hurts my OOP brain

In:

fsetIntervalList[interval_, data_] := Module[{v = interval, d = data},
  array = {}; 
  For[i = 0, i < Length[d], i++, 
   If[d[[i + 1]] == 0, Continue[], 
    If[i == 0 || d[[i]] == 0, AppendTo[array, {i*v, i*v + v}], 
     array[[Length[array]]][[2]] += v]]
   ];
  Return[array]
  ]

In:

fsetIntervalList[0.25, {1, 0, 0, 1, 1, 0}]

Out:

{{0., 0.25}, {0.75, 1.25}}
$\endgroup$
4
  • $\begingroup$ Output: { } ? $\endgroup$
    – Syed
    Commented Nov 11, 2021 at 3:42
  • $\begingroup$ The first output was { }, missed ; behind array = {}; so there should be only one output, by calling array. Which is not the best obviously. $\endgroup$
    – dzCodes
    Commented Nov 11, 2021 at 18:21
  • $\begingroup$ Thanks for the correction. I cannot say that I understand your explanation. Perhaps someone with a better understanding of this particular problem will respond to your post. In order to help that person, please add to your post the input for which you show this array output. $\endgroup$
    – Syed
    Commented Nov 11, 2021 at 18:46
  • $\begingroup$ thanks @Syed I understand my code might have been the most confusing thing there, I edited it to use Module and return the actual output from the method. I hope it makes more sense. $\endgroup$
    – dzCodes
    Commented Nov 11, 2021 at 19:39

1 Answer 1

0
$\begingroup$
fsetIntervalList[v_, bits_] :=
 With[{g = SplitBy[Range@Length@bits, bits[[#]] &]},
  {#[[1]], #[[1]] + Length@#} v & /@ (Select[g, bits[[#]][[1]] == 1 &] - 1)]
fsetIntervalList[0.25, {1, 0, 0, 1, 1, 0}]
(* {{0., 0.25}, {0.75, 1.25}} *)
$\endgroup$
1
  • 1
    $\begingroup$ The clever bit here is to do: SplitBy[Range@Length@bits, bits[[#]] &] which takes a list of positions {1,2,3,4,...,n} and splits them into runs where there are corresponding runs in the bits list, so {1,0,0,1,1,0} groups as {{1},{0,0},{1,1},{0}} which gives positions {{1},{2,3},{4,5},{6}}. You then just select the groups for the 1s only and -1 to zero-index your positions. The last thing to do is multiply and add v to get your intervals. $\endgroup$
    – flinty
    Commented Nov 11, 2021 at 22:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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