As the title, if I have a list:
{"", "", "", "2$70", ""}
I will expect:
{"", "", "", "2$70", "2$70"}
If I have
{"", "", "", "3$71", "", "2$72", ""}
then:
{"", "", "", "3$71", "3$71", "2$72", "2$72"}
And
{"", "", "", "3$71", "","", "2$72", ""}
should give
{"", "", "", "3$71", "3$71", "", "2$72", "2$72"}
This is my try:
{"", "", "", "2$70", ""} /. {p : Except["", String], ""} :> {p, p}
But I don't know why it doesn't work. Poor ability of pattern match. Can anybody give some advice?
Answer
As I presently interpret the question
(Now with refinements after considering Chris Degnen's simultaneous answer)
fn[list_] :=
Partition[list, 2, 1, -1, ""] // Cases[{p_, ""} | {_, p_} :> p]
Test:
{"", "x", "y", "", "z", ""} // fn
{"", "x", "y", "y", "z", "z"}
Patterns
Since you seem only to be interested in a pattern-matching solution here is my proposal to avoid the extremely slow use of ReplaceRepeated
while still using pattern-matching as the core of the operation.
fn2[list_] :=
list // ReplacePart @
ReplaceList[list, {a___, p_, "", ___} :> (2 + Length@{a} -> p)]
Recursive replacement
I just realized that this is a perfect time to use a self-referential replacement:
fn3[list_] :=
list /. {a___, p_, "", b___} :> {a, p, p, ##& @@ fn3@{b}}
Benchmark
All three methods are much faster than kglr's foo
(note the log-log scale).
Now with Carl Woll's fc
, the fastest method yet. ( but no patterns ;-) )
Needs["GeneralUtilities`"]
$RecursionLimit = 1*^5;
BenchmarkPlot[{foo, fn, fn2, fn3, fc},
RandomChoice[{"", "", "", "a", "b"}, #] &
]
Comments
Post a Comment