7
$\begingroup$

I have list: {{a, b}, {c, d}, {e, f}}

What is the most simple (but automated) way to add this data to the list?

{{a, 0}, {a, b}, {c, 0}, {c, d}, {e, 0}, {e, f}}
$\endgroup$

9 Answers 9

13
$\begingroup$

You can use a replacement rule like

{{a, b}, {c, d}, {e, f}} /. {x_, y_} :> 
  Sequence[{x, 0}, {x, y}]
(* {{a, 0}, {a, b}, {c, 0}, {c, d}, {e, 0}, {e, f}} *)
$\endgroup$
2
  • 5
    $\begingroup$ Just need to be careful that the top-level list must never have only two elements, otherwise the pattern will match that. $\endgroup$
    – mikado
    Commented Jul 11, 2016 at 19:47
  • 5
    $\begingroup$ Also, be wary of what happens when your list of ordered pairs is only two elements long. To get around that issue, use Replace with a level-spec: Replace[{{a, b}, {c, d}}, {x_, y_} :> Sequence[{x, 0}, {x, y}], 2] $\endgroup$
    – march
    Commented Jul 11, 2016 at 20:42
11
$\begingroup$

A couple of other methods. We take

lst = {{a, b}, {c, d}, {e, f}};

Three directly related ones:

Table[{j {1, 0}, j}, {j, lst}]~Flatten~1
Flatten[{# {1, 0}, #} & /@ lst, 1]
Flatten[{{#1, 0}, {#1, #2}} & @@@ lst, 1]

A relatively concise one using Riffle:

Riffle[# {1, 0} & /@ #, #] &@lst

And a somewhat silly way:

Hold@Sequence[# {1, 0}, #] & /@ lst // ReleaseHold

Or, from a comment by Gerli:

Apply[Sequence, {# {1, 0}, #}] & /@ lst
$\endgroup$
4
  • 1
    $\begingroup$ Slight variant for Riffle: Riffle[ #.{{1, 0}, {0, 0}}, #] &@lst $\endgroup$
    – user1066
    Commented Jul 11, 2016 at 21:14
  • 1
    $\begingroup$ Instead of Hold[Sequence[...]] // ReleaseHold you could use Apply[Sequence, {...}] $\endgroup$
    – Gerli
    Commented Jul 12, 2016 at 11:49
  • 2
    $\begingroup$ also ## & @@ {{#, 0}, {##}} & @@@ lst (+1) $\endgroup$
    – kglr
    Commented Jul 12, 2016 at 16:21
  • 1
    $\begingroup$ @kglr. That is amazing. All operator forms! $\endgroup$
    – march
    Commented Jul 12, 2016 at 16:23
4
$\begingroup$
## &[{#, 0}, {##}] & @@@ lst

{{a, 0}, {a, b}, {c, 0}, {c, d}, {e, 0}, {e, f}}

$\endgroup$
2
$\begingroup$
list = {{a, b}, {c, d}, {e, f}};

Riffle[MapAt[0 &, {;;, 2}] @ list, list]

{{a, 0}, {a, b}, {c, 0}, {c, d}, {e, 0}, {e, f}}

$\endgroup$
2
$\begingroup$
Splice[{{#, 0}, {##}}] & @@@ lis

{{a, 0}, {a, b}, {c, 0}, {c, d}, {e, 0}, {e, f}}

$\endgroup$
2
$\begingroup$

Another way using Fold:

lst = {{a, b}, {c, d}, {e, f}};

Fold[Join[#1, {{First@#2, 0}, #2}] &, {}, lst]

(*{{a, 0}, {a, b}, {c, 0}, {c, d}, {e, 0}, {e, f}}*)
$\endgroup$
2
$\begingroup$
MapThread[Sequence,{Thread[List[#[[All,1]],0]],#}]&@lst

(* {{a,0},{a,b},{c,0},{c,d},{e,0},{e,f}} *)

Or

Thread[Hold[Sequence][Thread[List[#[[All,1]],0]],#]]&@lst//ReleaseHold

(* {{a,0},{a,b},{c,0},{c,d},{e,0},{e,f}} *)
$\endgroup$
2
$\begingroup$
list = {{a, b}, {c, d}, {e, f}};

Using Cases and ReplaceAt (new in 13.1)

Cases[list, x_ :> Sequence[ReplaceAt[x, _ :> 0, 2], x]]

{{a, 0}, {a, b}, {c, 0}, {c, d}, {e, 0}, {e, f}}

$\endgroup$
2
$\begingroup$
lst={{a, b}, {c, d}, {e, f}};

Another way using ReplaceList:

ReplaceList[lst,{___,{a_,b_},___}:>Splice@{{a,0},{a,b}}]

{{a,0},{a,b},{c,0},{c,d},{e,0},{e,f}}

Or using SequenceCases:

SequenceCases[lst,{{a_,b_}}:>Splice@{{a,0},{a,b}}]

{{a,0},{a,b},{c,0},{c,d},{e,0},{e,f}}

$\endgroup$

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.