Message Boards Message Boards

0
|
4657 Views
|
11 Replies
|
8 Total Likes
View groups...
Share
Share this post:

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

Posted 5 years ago

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

POSTED BY: Gregory Lypny
11 Replies
Posted 5 years ago

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

POSTED BY: Gregory Lypny
Posted 5 years ago

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

POSTED BY: Gregory Lypny

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

POSTED BY: Sander Huisman

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

POSTED BY: Sander Huisman
Posted 5 years ago

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

POSTED BY: Gregory Lypny
Posted 5 years ago

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

Greg

POSTED BY: Gregory Lypny

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}
POSTED BY: Gianluca Gorni

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

POSTED BY: Sander Huisman

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…

POSTED BY: Sander Huisman
Posted 5 years ago

Brilliant, Sander!

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

Many thanks,

Greg

POSTED BY: Gregory Lypny

I would use SequenceReplace:

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

where a is your input list.

POSTED BY: Sander Huisman
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