List manipulation - adding last element of sublist to each sublist
lst = {{}, {1, 2}, {}, {2, 4, 3}, {5, 4, 3, 2}, {}} ;
Join[lst, (lst /. {} -> {0})[[All, {-1}]], 2]
{{0}, {1, 2, 2}, {0}, {2, 4, 3, 3}, {5, 4, 3, 2, 2}, {0}}
Also
ClearAll[f]; f[{}] = {0}; f[{a___, b_}] := {a, b, b};
f /@ {{}, {1, 2}, {}, {2, 4, 3}, {5, 4, 3, 2}, {}}
{{0}, {1, 2, 2}, {0}, {2, 4, 3, 3}, {5, 4, 3, 2, 2}, {0}}
Timings:
ClearAll[f0, f1, f2, f3, f4, f5];
f0[{}] = {0}; f0[{a___, b_}] := {a, b, b};
f1 = f0 /@ # &;
f2 = Join[#, (# /. {} -> {0})[[All, {-1}]], 2] &;
f3 = Replace[#, {{a___, last_} :> {a, last, last}, {} -> {0}}, -1] &; (*MarcoB *)
f4 = Replace[#, {a___, b_} | {} :> {a, b, b + 0}, {1}] &; (* Mr.Wizard *)
f5 = # /. {{} -> {0}, _ :> # ~ Join~{#[[-1]]}} & /@ # &; (* Fraccalo *)
f6 = Append[#, If[# == {}, 0, #[[-1]]]] & /@ # &; (* GIM *)
SeedRandom[1]
testlst = RandomInteger[10, #] & /@ RandomInteger[10, 1000000];
t1 = First[AbsoluteTiming[r1 = f1@testlst;]];
t2 = First[AbsoluteTiming[r2 = f2@testlst;]];
t3 = First[AbsoluteTiming[r3 = f3@testlst;]];
t4 = First[AbsoluteTiming[r4 = f4@testlst;]];
t5 = First[AbsoluteTiming[r5 = f5@testlst;]];
t6 = First[AbsoluteTiming[r6 = f6@testlst;]];
Equal[r1, r2, r3, r4, r5, r6]
True
Grid[Prepend[SortBy[Transpose[{{"f1", "f2", "f3", "f4", "f5", "f6"},
{t1, t2, t3, t4, t5, t6}}], Last], {"function", "timing"}], Dividers -> All]
Replace[
{{}, {1, 2}, {}, {2, 4, 3}, {5, 4, 3, 2}, {}},
{{a___, last_} :> {a, last, last}, {} -> {0}},
-1
]
(* Out: {{0}, {1, 2, 2}, {0}, {2, 4, 3, 3}, {5, 4, 3, 2, 2}, {0}} *)
A single-Rule method using Alternatives
:
in = {{}, {1, 2}, {}, {2, 4, 3}, {5, 4, 3, 2}, {}};
Replace[in, {a___, b_} | {} :> {a, b, b + 0}, {1}]
{{0}, {1, 2, 2}, {0}, {2, 4, 3, 3}, {5, 4, 3, 2, 2}, {0}}
Some additional examples that may help in understanding this code:
- Alternatives pattern in a function definition