Message Boards Message Boards

GROUPS:

Best Way to Find and Replace Adjacent Elements in a List?

Posted 3 months ago
485 Views
|
11 Replies
|
8 Total Likes
|

Hi everyone,

I have a function that returns a list with a series of boolean value False followed by a series of boolean value True like this:

{False, False, False, True, True, True, True, True}

The False's always come before the True's, and the number of False's does not have to equal the number of True's. I need to replace the last False in the series—the third one in my example—with True. This works

Flatten[ReplaceAll[
  Split[{False, False, False, True, True, True, True, 
    True}, #1 =!= #2 &], {False, True} -> {True, True}]]

but it seems like there should be a simpler or more elegant way. Any thoughts?

Greg

11 Replies

I would use SequenceReplace:

SequenceReplace[a, {False, True} -> Sequence[True, True]]

where a is your input list.

Brilliant, Sander!

I use Sequence so rarely that it never occurred to me that there may be a SequenceReplace function.

Many thanks,

Greg

it's a new function since 11.3 so, actually, this also has been my first use-case… combinations of Split, or just regular replace also generally works fine (and faster).

Not sure about the performance of sequence replace, and if it is critical…

For earlier versions of Mathematica we can manage like this:

{False, False, False, True, True, True, True, 
  True} /.
 {smth1___, False, True, smth2___} :>
  {smth1, True, True, smth2}

This would replace just the first occurrence of it, and is therefore very different.

Yes, of course, a delayed rule. Good stuff! Very fast.

Greg

Good point. My function is restricted in its use and is applied only to situations where there is just one occurrence of the pattern. Your way, however, has an advantage if error-checking for more than one occurrence needs to be built in.

Greg

If it is really of the form: False False … … True True True, you can also use solutions like:

p = LengthWhile[a, Not@*TrueQ]
a[[p]] = True;

or even just:

Append[Rest[a], True]

or

Rest[RotateLeft[Prepend[a, True]]]

or

(c = #; c[[-1]] = True; c) &[RotateLeft[a]]

or

Most[RotateLeft[Prepend[a, True], 2]]

or

ReplacePart[RotateLeft[a], -1 -> True]

or

etc etc

That's pretty slick. Something for me to brush up on because I can see where I can see some other neat uses.

Thanks again,

Greg

I added a few more, but yeah, at least 20 different ways of doing this…

Append[Rest[a], True] is definitely the neatest I think…

--SH

That's what's cool about bouncing ideas around: you discover or rediscover approaches that you can use to make your code faster or more reliable and apply to other things.

Greg

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract