# Build a new flat list from a mix of part items and part spans

I want to modify a list of table row by adding an extra column. For that I Map the data with a pure function that evluate the new column value from exisiting one and reconstruct a new list from that and the initial Parts of the list:

b = 5000
data = {{1, 45000., 27500., "Inverted"},
{2, 22500., 18333.3, ""},
{3, 15000., 13750., "Inverted"},
{4, 11250., 11000., ""},
{5, 9000., 9166.67, "Inverted"},
{6, 7500., 7857.14, ""},
{7, 6428.57, 6875., "Inverted"}}

{#[[1;;3]], #[[1]]> 2b, #[[4]]} & /@ data

{{{1,45000.,27500.},False,Inverted},
{{2,22500.,18333.3},False,},
{{3,15000.,13750.},False,Inverted},
{{4,11250.,11000.},False,},
{{5,9000.,9166.67},False,Inverted},
{{6,7500.,7857.14},False,},
{{7,6428.57,6875.},False,Inverted}}


The problem is #[[1;;3]] return a list--so I end-up with nested list instead of flat records.

As a workarround, I Flatten each record:

    Flatten[{#[[1;;3]], #[[1]]> 2b, #[[4]]}] & /@ data

{{1,45000.,27500.,False,Inverted},
{2,22500.,18333.3,False,},
{3,15000.,13750.,False,Inverted},
{4,11250.,11000.,False,},
{5,9000.,9166.67,False,Inverted},
{6,7500.,7857.14,False,},
{7,6428.57,6875.,False,Inverted}}

Flatten[{#[[1;;3]], #[[1]]> 2b, #[[4]]}] & /@ data


It works in that particular case. But it is not entirely satisfactory since, if the initial record would already contain list items, they would have been flattened too.

If there a more generic solution to build a list from items and list spans?

• Thanks @Marco. I didn't have yet encountered the :> notation. I need to take a look at that! Commented Dec 9, 2019 at 23:00
• Sylvain, yes, both @@@ (i.e. Apply at level 1) and RuleDelayed are worth looking into! Commented Dec 9, 2019 at 23:02

{## & @@ #[[1 ;; 3]], #[[1]] > 2 b, #[[4]]} & /@ data


or

{Sequence @@ #[[1 ;; 3]], #[[1]] > 2 b, #[[4]]} & /@ data


{{1, 45000., 27500., False, "Inverted"},
{2, 22500., 18333.3, False, ""},
{3, 15000., 13750., False, "Inverted"},
{4, 11250., 11000., False, ""},
{5, 9000., 9166.67, False, "Inverted"},
{6, 7500., 7857.14, False, ""},
{7, 6428.57, 6875., False, "Inverted"}}

• Thnaks, @kglr, you gave me an idea ;) Commented Dec 9, 2019 at 23:15

Two options presented themselves to me, using Apply or using replacements:

{#1, #2, #3, #1 > 2 b, #4} & @@@ data
data /. {x_, y_, z_, p_} :> {x, y, z, x > 2 b, p}


Both reproduce your results.

Another alternative: Join[#[[1 ;; 3]], {#[[1]] > 2 b, #[[4]]}] & /@ data

While posting my question, the system suggested me the , which in its turn lead me to the Catenate function. It works at the expense of few additional brackets:

Catenate[{#[[1;;3]], {#[[1]]> 2b}, {#[[4]]}}] & /@ data
(*                   ^          ^  ^      ^

{{1,45000.,27500.,False,Inverted},{2,22500.,18333.3,False,},{3,15000.,13750.,False,Inverted},{4,11250.,11000.,False,},{5,9000.,9166.67,False,Inverted},{6,7500.,7857.14,False,},{7,6428.57,6875.,False,Inverted}}


Somewhat a variation around the Sequence symbol that was suggeste by @kglr in another answer:

{#[[1;;3]] /. List -> Sequence, #[[1]]> 2b, #[[4]]} & /@ data