2
$\begingroup$

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?

$\endgroup$
  • $\begingroup$ Thanks @Marco. I didn't have yet encountered the :> notation. I need to take a look at that! $\endgroup$ – Sylvain Leroux Dec 9 '19 at 23:00
  • 1
    $\begingroup$ Sylvain, yes, both @@@ (i.e. Apply at level 1) and RuleDelayed are worth looking into! $\endgroup$ – MarcoB Dec 9 '19 at 23:02
4
$\begingroup$
{## & @@ #[[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"}}

$\endgroup$
3
$\begingroup$

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.

$\endgroup$
2
$\begingroup$

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

$\endgroup$
0
$\begingroup$

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}}
$\endgroup$
0
$\begingroup$

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

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.