Duplicating an array's elements using functional programming









up vote
6
down vote

favorite












I'm trying to duplicate each element in an array, but using functional style.



I have this currently:



["a", "b", "c"]


And I'm getting this:



["a","a","b","b","c","c"]


So far I have tried the following, mapping each element to an array, then using flat() to get a 1d array. Is there a cleaner way because it feels like I'm abusing map and flat.



["a", "b", "c"].map(item => [item, item]).flat();


Is there a better way to do this?




I was trying to provide a example as simple as possible but left some details out. The real input is not sorted because elements are not comparable.
It's something like:



[

a:"a"
b:"b"
,

c: 1
d: 2
,

apple: ,
sellers: ["me", "her"]

]


The duplicated result should be something like this, where duplicated elements are next to each other:



[

a:"a"
b:"b"
,

a:"a"
b:"b"
,

c: 1
d: 2
,

c: 1
d: 2
,

apple: ,
sellers: ["me", "her"]
,

apple: ,
sellers: ["me", "her"]

]









share|improve this question























  • It would be helpful if you edited your question to include: 1. Is the input array always sorted as in your example? 2. Should the order of the output match the order of the input? Several of the answers assume sorted input.
    – Matt Morgan
    Nov 11 at 1:35











  • If you don't consider complexity and performance , than , basically you can use destructuring [...arr,...arr].sort(). And by the way functional programming does not refer to Arrow-Functions (as you used in your example) but rather the behavior and meaning of the function which should act like Mathematical functions by receiving parameters and returning result. So in your case you would like to write something like this (to align with functional programming): const duplicateArrayItems = (arr) => [...arr,...arr].sort(); let array = ['a','b','c'], result = duplicateArrayItems(array);
    – Nirit Levi
    Nov 11 at 7:09











  • @MattMorgan thanks for pointing that out, I was trying to provide an example as simple as possible but that caused important details to be left out. 1) input is not sorted because the real actual input is an array of complex objects that are not sortable. 2) the order of the output should be like a,a,b,b,c,c duplicated elements are next to each other
    – Reek
    Nov 11 at 11:21










  • @Reek thanks for the clarification. I've edited my answer to reflect your new input data.
    – Matt Morgan
    Nov 11 at 12:12














up vote
6
down vote

favorite












I'm trying to duplicate each element in an array, but using functional style.



I have this currently:



["a", "b", "c"]


And I'm getting this:



["a","a","b","b","c","c"]


So far I have tried the following, mapping each element to an array, then using flat() to get a 1d array. Is there a cleaner way because it feels like I'm abusing map and flat.



["a", "b", "c"].map(item => [item, item]).flat();


Is there a better way to do this?




I was trying to provide a example as simple as possible but left some details out. The real input is not sorted because elements are not comparable.
It's something like:



[

a:"a"
b:"b"
,

c: 1
d: 2
,

apple: ,
sellers: ["me", "her"]

]


The duplicated result should be something like this, where duplicated elements are next to each other:



[

a:"a"
b:"b"
,

a:"a"
b:"b"
,

c: 1
d: 2
,

c: 1
d: 2
,

apple: ,
sellers: ["me", "her"]
,

apple: ,
sellers: ["me", "her"]

]









share|improve this question























  • It would be helpful if you edited your question to include: 1. Is the input array always sorted as in your example? 2. Should the order of the output match the order of the input? Several of the answers assume sorted input.
    – Matt Morgan
    Nov 11 at 1:35











  • If you don't consider complexity and performance , than , basically you can use destructuring [...arr,...arr].sort(). And by the way functional programming does not refer to Arrow-Functions (as you used in your example) but rather the behavior and meaning of the function which should act like Mathematical functions by receiving parameters and returning result. So in your case you would like to write something like this (to align with functional programming): const duplicateArrayItems = (arr) => [...arr,...arr].sort(); let array = ['a','b','c'], result = duplicateArrayItems(array);
    – Nirit Levi
    Nov 11 at 7:09











  • @MattMorgan thanks for pointing that out, I was trying to provide an example as simple as possible but that caused important details to be left out. 1) input is not sorted because the real actual input is an array of complex objects that are not sortable. 2) the order of the output should be like a,a,b,b,c,c duplicated elements are next to each other
    – Reek
    Nov 11 at 11:21










  • @Reek thanks for the clarification. I've edited my answer to reflect your new input data.
    – Matt Morgan
    Nov 11 at 12:12












up vote
6
down vote

favorite









up vote
6
down vote

favorite











I'm trying to duplicate each element in an array, but using functional style.



I have this currently:



["a", "b", "c"]


And I'm getting this:



["a","a","b","b","c","c"]


So far I have tried the following, mapping each element to an array, then using flat() to get a 1d array. Is there a cleaner way because it feels like I'm abusing map and flat.



["a", "b", "c"].map(item => [item, item]).flat();


Is there a better way to do this?




I was trying to provide a example as simple as possible but left some details out. The real input is not sorted because elements are not comparable.
It's something like:



[

a:"a"
b:"b"
,

c: 1
d: 2
,

apple: ,
sellers: ["me", "her"]

]


The duplicated result should be something like this, where duplicated elements are next to each other:



[

a:"a"
b:"b"
,

a:"a"
b:"b"
,

c: 1
d: 2
,

c: 1
d: 2
,

apple: ,
sellers: ["me", "her"]
,

apple: ,
sellers: ["me", "her"]

]









share|improve this question















I'm trying to duplicate each element in an array, but using functional style.



I have this currently:



["a", "b", "c"]


And I'm getting this:



["a","a","b","b","c","c"]


So far I have tried the following, mapping each element to an array, then using flat() to get a 1d array. Is there a cleaner way because it feels like I'm abusing map and flat.



["a", "b", "c"].map(item => [item, item]).flat();


Is there a better way to do this?




I was trying to provide a example as simple as possible but left some details out. The real input is not sorted because elements are not comparable.
It's something like:



[

a:"a"
b:"b"
,

c: 1
d: 2
,

apple: ,
sellers: ["me", "her"]

]


The duplicated result should be something like this, where duplicated elements are next to each other:



[

a:"a"
b:"b"
,

a:"a"
b:"b"
,

c: 1
d: 2
,

c: 1
d: 2
,

apple: ,
sellers: ["me", "her"]
,

apple: ,
sellers: ["me", "her"]

]






javascript functional-programming






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 11 at 11:28

























asked Nov 11 at 1:06









Reek

8551230




8551230











  • It would be helpful if you edited your question to include: 1. Is the input array always sorted as in your example? 2. Should the order of the output match the order of the input? Several of the answers assume sorted input.
    – Matt Morgan
    Nov 11 at 1:35











  • If you don't consider complexity and performance , than , basically you can use destructuring [...arr,...arr].sort(). And by the way functional programming does not refer to Arrow-Functions (as you used in your example) but rather the behavior and meaning of the function which should act like Mathematical functions by receiving parameters and returning result. So in your case you would like to write something like this (to align with functional programming): const duplicateArrayItems = (arr) => [...arr,...arr].sort(); let array = ['a','b','c'], result = duplicateArrayItems(array);
    – Nirit Levi
    Nov 11 at 7:09











  • @MattMorgan thanks for pointing that out, I was trying to provide an example as simple as possible but that caused important details to be left out. 1) input is not sorted because the real actual input is an array of complex objects that are not sortable. 2) the order of the output should be like a,a,b,b,c,c duplicated elements are next to each other
    – Reek
    Nov 11 at 11:21










  • @Reek thanks for the clarification. I've edited my answer to reflect your new input data.
    – Matt Morgan
    Nov 11 at 12:12
















  • It would be helpful if you edited your question to include: 1. Is the input array always sorted as in your example? 2. Should the order of the output match the order of the input? Several of the answers assume sorted input.
    – Matt Morgan
    Nov 11 at 1:35











  • If you don't consider complexity and performance , than , basically you can use destructuring [...arr,...arr].sort(). And by the way functional programming does not refer to Arrow-Functions (as you used in your example) but rather the behavior and meaning of the function which should act like Mathematical functions by receiving parameters and returning result. So in your case you would like to write something like this (to align with functional programming): const duplicateArrayItems = (arr) => [...arr,...arr].sort(); let array = ['a','b','c'], result = duplicateArrayItems(array);
    – Nirit Levi
    Nov 11 at 7:09











  • @MattMorgan thanks for pointing that out, I was trying to provide an example as simple as possible but that caused important details to be left out. 1) input is not sorted because the real actual input is an array of complex objects that are not sortable. 2) the order of the output should be like a,a,b,b,c,c duplicated elements are next to each other
    – Reek
    Nov 11 at 11:21










  • @Reek thanks for the clarification. I've edited my answer to reflect your new input data.
    – Matt Morgan
    Nov 11 at 12:12















It would be helpful if you edited your question to include: 1. Is the input array always sorted as in your example? 2. Should the order of the output match the order of the input? Several of the answers assume sorted input.
– Matt Morgan
Nov 11 at 1:35





It would be helpful if you edited your question to include: 1. Is the input array always sorted as in your example? 2. Should the order of the output match the order of the input? Several of the answers assume sorted input.
– Matt Morgan
Nov 11 at 1:35













If you don't consider complexity and performance , than , basically you can use destructuring [...arr,...arr].sort(). And by the way functional programming does not refer to Arrow-Functions (as you used in your example) but rather the behavior and meaning of the function which should act like Mathematical functions by receiving parameters and returning result. So in your case you would like to write something like this (to align with functional programming): const duplicateArrayItems = (arr) => [...arr,...arr].sort(); let array = ['a','b','c'], result = duplicateArrayItems(array);
– Nirit Levi
Nov 11 at 7:09





If you don't consider complexity and performance , than , basically you can use destructuring [...arr,...arr].sort(). And by the way functional programming does not refer to Arrow-Functions (as you used in your example) but rather the behavior and meaning of the function which should act like Mathematical functions by receiving parameters and returning result. So in your case you would like to write something like this (to align with functional programming): const duplicateArrayItems = (arr) => [...arr,...arr].sort(); let array = ['a','b','c'], result = duplicateArrayItems(array);
– Nirit Levi
Nov 11 at 7:09













@MattMorgan thanks for pointing that out, I was trying to provide an example as simple as possible but that caused important details to be left out. 1) input is not sorted because the real actual input is an array of complex objects that are not sortable. 2) the order of the output should be like a,a,b,b,c,c duplicated elements are next to each other
– Reek
Nov 11 at 11:21




@MattMorgan thanks for pointing that out, I was trying to provide an example as simple as possible but that caused important details to be left out. 1) input is not sorted because the real actual input is an array of complex objects that are not sortable. 2) the order of the output should be like a,a,b,b,c,c duplicated elements are next to each other
– Reek
Nov 11 at 11:21












@Reek thanks for the clarification. I've edited my answer to reflect your new input data.
– Matt Morgan
Nov 11 at 12:12




@Reek thanks for the clarification. I've edited my answer to reflect your new input data.
– Matt Morgan
Nov 11 at 12:12












4 Answers
4






active

oldest

votes

















up vote
6
down vote













Array.reduce is semantically the appropriate method here: take an object (in this case an array) and return an object of a different type, or with a different length or shape (note: edited to use Array.push for faster performance per @slider suggestion):



EDIT: I've edited my answer to reflect OP's updated input data. Note also, that this solution is cross-browser and NodeJS compatible without requiring transpilation.






let data = [

a:"a",
b:"b",
,

c: 1,
d: 2
,

apple: ,
sellers: ["me", "her"]

];

let result = data
.reduce((acc, el) =>
acc.push(el, el);
return acc;
, );

console.log(JSON.stringify(result, null, 2));





Otherwise you could map each element, duplicating it, then combine them:






let data = [

a:"a",
b:"b",
,

c: 1,
d: 2
,

apple: ,
sellers: ["me", "her"]

];

let result = data.map(item => [item, item]).reduce((acc, arr) => acc.concat(arr));

console.log(JSON.stringify(result, null, 2));





As mentioned in other answers here, either of these approaches have the advantage of not requiring the original array to have been sorted.






share|improve this answer






















  • concat also takes multiple arguments ... => acc.concat(el, el)
    – charlietfl
    Nov 11 at 1:13







  • 1




    Reduce is overkill. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
    – kemicofa
    Nov 11 at 1:16










  • @kemicofa using concat().sort() as a few have suggested only works when the original array was sorted. If you have a better suggestion please post an answer.
    – Matt Morgan
    Nov 11 at 1:22






  • 1




    acc.concat(el).concat(el) may be less code but it's much worse time complexity. I would use push(el, el) with a return acc statement because push is O(1) as opposed to concat which is O(n) since it's building a new array.
    – slider
    Nov 11 at 1:28










  • @slider thanks for the suggestion! That sounds like a great optimization.
    – Matt Morgan
    Nov 11 at 1:30

















up vote
4
down vote













I would recommend Array.prototype.flatMap






const twice = x =>
[ x, x ]

console.log
( [ 'a', 'b', 'c' ] .flatMap (twice) // [ 'a', 'a', 'b', 'b', 'c', 'c' ]
, [ 1, 2, 3, 4, 5 ] .flatMap (twice) // [ 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 ]
)





flatMap is useful for all kinds of things






const tree =
[ 0, [ 1 ], [ 2, [ 3 ], [ 4, [ 5 ] ] ] ]

const all = ([ value, ...children ]) =>
[ value ] .concat (children .flatMap (all))

console.log (all (tree))
// [ 0, 1, 2, 3, 4, 5 ]





really cool things






const ranks =
[ 'J', 'Q', 'K', 'A' ]

const suits =
[ '♡', '♢', '♤', '♧' ]

console.log
( ranks .flatMap (r =>
suits .flatMap (s =>
[ [ r, s ] ]
)
)
)

// [ ['J','♡'], ['J','♢'], ['J','♤'], ['J','♧']
// , ['Q','♡'], ['Q','♢'], ['Q','♤'], ['Q','♧']
// , ['K','♡'], ['K','♢'], ['K','♤'], ['K','♧']
// , ['A','♡'], ['A','♢'], ['A','♤'], ['A','♧']
// ]








share|improve this answer


















  • 1




    That is really nice, although of limited practical use until there’s Microsoft and Node support.
    – Mark Meyer
    Nov 11 at 6:39


















up vote
4
down vote













You can use the function reduce and concatenate the same object on each iteration.






let array = ["a", "b", "c"],
result = array.reduce((a, c) => a.concat(c, c), );

console.log(result);

.as-console-wrapper max-height: 100% !important; top: 0; 








share|improve this answer






















  • Is Array.prototype.concat.call... really necessary? Couldn't this just be done by array.concat(array).sort()?
    – George Jempty
    Nov 11 at 1:12






  • 1




    Makes sense. There's still more than one way to do it. For instance by making a copy of the original array with slice
    – George Jempty
    Nov 11 at 1:14






  • 1




    How's array.concat(array) going to mutate the original? The docs say "This method does not change the existing arrays, but instead returns a new array."
    – slider
    Nov 11 at 1:16










  • Also this assumes the original array is sorted. What if the original is ['b', 'a', 'c']?
    – slider
    Nov 11 at 1:17






  • 1




    Well, with ['b', 'a', 'c'] this will result in ["a","a","b","b","c","c"] but the desired output may be ['b', 'b', 'a', 'a', 'c', 'c'] (I'm not sure though).
    – slider
    Nov 11 at 1:20

















up vote
2
down vote













You could just do this:



var arr = ["a", "b", "c"];
arr = arr.concat(arr).sort();


This is one of the simplest methods to do what you are asking to do.






share|improve this answer






















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53244954%2fduplicating-an-arrays-elements-using-functional-programming%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    6
    down vote













    Array.reduce is semantically the appropriate method here: take an object (in this case an array) and return an object of a different type, or with a different length or shape (note: edited to use Array.push for faster performance per @slider suggestion):



    EDIT: I've edited my answer to reflect OP's updated input data. Note also, that this solution is cross-browser and NodeJS compatible without requiring transpilation.






    let data = [

    a:"a",
    b:"b",
    ,

    c: 1,
    d: 2
    ,

    apple: ,
    sellers: ["me", "her"]

    ];

    let result = data
    .reduce((acc, el) =>
    acc.push(el, el);
    return acc;
    , );

    console.log(JSON.stringify(result, null, 2));





    Otherwise you could map each element, duplicating it, then combine them:






    let data = [

    a:"a",
    b:"b",
    ,

    c: 1,
    d: 2
    ,

    apple: ,
    sellers: ["me", "her"]

    ];

    let result = data.map(item => [item, item]).reduce((acc, arr) => acc.concat(arr));

    console.log(JSON.stringify(result, null, 2));





    As mentioned in other answers here, either of these approaches have the advantage of not requiring the original array to have been sorted.






    share|improve this answer






















    • concat also takes multiple arguments ... => acc.concat(el, el)
      – charlietfl
      Nov 11 at 1:13







    • 1




      Reduce is overkill. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
      – kemicofa
      Nov 11 at 1:16










    • @kemicofa using concat().sort() as a few have suggested only works when the original array was sorted. If you have a better suggestion please post an answer.
      – Matt Morgan
      Nov 11 at 1:22






    • 1




      acc.concat(el).concat(el) may be less code but it's much worse time complexity. I would use push(el, el) with a return acc statement because push is O(1) as opposed to concat which is O(n) since it's building a new array.
      – slider
      Nov 11 at 1:28










    • @slider thanks for the suggestion! That sounds like a great optimization.
      – Matt Morgan
      Nov 11 at 1:30














    up vote
    6
    down vote













    Array.reduce is semantically the appropriate method here: take an object (in this case an array) and return an object of a different type, or with a different length or shape (note: edited to use Array.push for faster performance per @slider suggestion):



    EDIT: I've edited my answer to reflect OP's updated input data. Note also, that this solution is cross-browser and NodeJS compatible without requiring transpilation.






    let data = [

    a:"a",
    b:"b",
    ,

    c: 1,
    d: 2
    ,

    apple: ,
    sellers: ["me", "her"]

    ];

    let result = data
    .reduce((acc, el) =>
    acc.push(el, el);
    return acc;
    , );

    console.log(JSON.stringify(result, null, 2));





    Otherwise you could map each element, duplicating it, then combine them:






    let data = [

    a:"a",
    b:"b",
    ,

    c: 1,
    d: 2
    ,

    apple: ,
    sellers: ["me", "her"]

    ];

    let result = data.map(item => [item, item]).reduce((acc, arr) => acc.concat(arr));

    console.log(JSON.stringify(result, null, 2));





    As mentioned in other answers here, either of these approaches have the advantage of not requiring the original array to have been sorted.






    share|improve this answer






















    • concat also takes multiple arguments ... => acc.concat(el, el)
      – charlietfl
      Nov 11 at 1:13







    • 1




      Reduce is overkill. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
      – kemicofa
      Nov 11 at 1:16










    • @kemicofa using concat().sort() as a few have suggested only works when the original array was sorted. If you have a better suggestion please post an answer.
      – Matt Morgan
      Nov 11 at 1:22






    • 1




      acc.concat(el).concat(el) may be less code but it's much worse time complexity. I would use push(el, el) with a return acc statement because push is O(1) as opposed to concat which is O(n) since it's building a new array.
      – slider
      Nov 11 at 1:28










    • @slider thanks for the suggestion! That sounds like a great optimization.
      – Matt Morgan
      Nov 11 at 1:30












    up vote
    6
    down vote










    up vote
    6
    down vote









    Array.reduce is semantically the appropriate method here: take an object (in this case an array) and return an object of a different type, or with a different length or shape (note: edited to use Array.push for faster performance per @slider suggestion):



    EDIT: I've edited my answer to reflect OP's updated input data. Note also, that this solution is cross-browser and NodeJS compatible without requiring transpilation.






    let data = [

    a:"a",
    b:"b",
    ,

    c: 1,
    d: 2
    ,

    apple: ,
    sellers: ["me", "her"]

    ];

    let result = data
    .reduce((acc, el) =>
    acc.push(el, el);
    return acc;
    , );

    console.log(JSON.stringify(result, null, 2));





    Otherwise you could map each element, duplicating it, then combine them:






    let data = [

    a:"a",
    b:"b",
    ,

    c: 1,
    d: 2
    ,

    apple: ,
    sellers: ["me", "her"]

    ];

    let result = data.map(item => [item, item]).reduce((acc, arr) => acc.concat(arr));

    console.log(JSON.stringify(result, null, 2));





    As mentioned in other answers here, either of these approaches have the advantage of not requiring the original array to have been sorted.






    share|improve this answer














    Array.reduce is semantically the appropriate method here: take an object (in this case an array) and return an object of a different type, or with a different length or shape (note: edited to use Array.push for faster performance per @slider suggestion):



    EDIT: I've edited my answer to reflect OP's updated input data. Note also, that this solution is cross-browser and NodeJS compatible without requiring transpilation.






    let data = [

    a:"a",
    b:"b",
    ,

    c: 1,
    d: 2
    ,

    apple: ,
    sellers: ["me", "her"]

    ];

    let result = data
    .reduce((acc, el) =>
    acc.push(el, el);
    return acc;
    , );

    console.log(JSON.stringify(result, null, 2));





    Otherwise you could map each element, duplicating it, then combine them:






    let data = [

    a:"a",
    b:"b",
    ,

    c: 1,
    d: 2
    ,

    apple: ,
    sellers: ["me", "her"]

    ];

    let result = data.map(item => [item, item]).reduce((acc, arr) => acc.concat(arr));

    console.log(JSON.stringify(result, null, 2));





    As mentioned in other answers here, either of these approaches have the advantage of not requiring the original array to have been sorted.






    let data = [

    a:"a",
    b:"b",
    ,

    c: 1,
    d: 2
    ,

    apple: ,
    sellers: ["me", "her"]

    ];

    let result = data
    .reduce((acc, el) =>
    acc.push(el, el);
    return acc;
    , );

    console.log(JSON.stringify(result, null, 2));





    let data = [

    a:"a",
    b:"b",
    ,

    c: 1,
    d: 2
    ,

    apple: ,
    sellers: ["me", "her"]

    ];

    let result = data
    .reduce((acc, el) =>
    acc.push(el, el);
    return acc;
    , );

    console.log(JSON.stringify(result, null, 2));





    let data = [

    a:"a",
    b:"b",
    ,

    c: 1,
    d: 2
    ,

    apple: ,
    sellers: ["me", "her"]

    ];

    let result = data.map(item => [item, item]).reduce((acc, arr) => acc.concat(arr));

    console.log(JSON.stringify(result, null, 2));





    let data = [

    a:"a",
    b:"b",
    ,

    c: 1,
    d: 2
    ,

    apple: ,
    sellers: ["me", "her"]

    ];

    let result = data.map(item => [item, item]).reduce((acc, arr) => acc.concat(arr));

    console.log(JSON.stringify(result, null, 2));






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 11 at 12:21

























    answered Nov 11 at 1:11









    Matt Morgan

    2,0952719




    2,0952719











    • concat also takes multiple arguments ... => acc.concat(el, el)
      – charlietfl
      Nov 11 at 1:13







    • 1




      Reduce is overkill. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
      – kemicofa
      Nov 11 at 1:16










    • @kemicofa using concat().sort() as a few have suggested only works when the original array was sorted. If you have a better suggestion please post an answer.
      – Matt Morgan
      Nov 11 at 1:22






    • 1




      acc.concat(el).concat(el) may be less code but it's much worse time complexity. I would use push(el, el) with a return acc statement because push is O(1) as opposed to concat which is O(n) since it's building a new array.
      – slider
      Nov 11 at 1:28










    • @slider thanks for the suggestion! That sounds like a great optimization.
      – Matt Morgan
      Nov 11 at 1:30
















    • concat also takes multiple arguments ... => acc.concat(el, el)
      – charlietfl
      Nov 11 at 1:13







    • 1




      Reduce is overkill. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
      – kemicofa
      Nov 11 at 1:16










    • @kemicofa using concat().sort() as a few have suggested only works when the original array was sorted. If you have a better suggestion please post an answer.
      – Matt Morgan
      Nov 11 at 1:22






    • 1




      acc.concat(el).concat(el) may be less code but it's much worse time complexity. I would use push(el, el) with a return acc statement because push is O(1) as opposed to concat which is O(n) since it's building a new array.
      – slider
      Nov 11 at 1:28










    • @slider thanks for the suggestion! That sounds like a great optimization.
      – Matt Morgan
      Nov 11 at 1:30















    concat also takes multiple arguments ... => acc.concat(el, el)
    – charlietfl
    Nov 11 at 1:13





    concat also takes multiple arguments ... => acc.concat(el, el)
    – charlietfl
    Nov 11 at 1:13





    1




    1




    Reduce is overkill. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
    – kemicofa
    Nov 11 at 1:16




    Reduce is overkill. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
    – kemicofa
    Nov 11 at 1:16












    @kemicofa using concat().sort() as a few have suggested only works when the original array was sorted. If you have a better suggestion please post an answer.
    – Matt Morgan
    Nov 11 at 1:22




    @kemicofa using concat().sort() as a few have suggested only works when the original array was sorted. If you have a better suggestion please post an answer.
    – Matt Morgan
    Nov 11 at 1:22




    1




    1




    acc.concat(el).concat(el) may be less code but it's much worse time complexity. I would use push(el, el) with a return acc statement because push is O(1) as opposed to concat which is O(n) since it's building a new array.
    – slider
    Nov 11 at 1:28




    acc.concat(el).concat(el) may be less code but it's much worse time complexity. I would use push(el, el) with a return acc statement because push is O(1) as opposed to concat which is O(n) since it's building a new array.
    – slider
    Nov 11 at 1:28












    @slider thanks for the suggestion! That sounds like a great optimization.
    – Matt Morgan
    Nov 11 at 1:30




    @slider thanks for the suggestion! That sounds like a great optimization.
    – Matt Morgan
    Nov 11 at 1:30












    up vote
    4
    down vote













    I would recommend Array.prototype.flatMap






    const twice = x =>
    [ x, x ]

    console.log
    ( [ 'a', 'b', 'c' ] .flatMap (twice) // [ 'a', 'a', 'b', 'b', 'c', 'c' ]
    , [ 1, 2, 3, 4, 5 ] .flatMap (twice) // [ 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 ]
    )





    flatMap is useful for all kinds of things






    const tree =
    [ 0, [ 1 ], [ 2, [ 3 ], [ 4, [ 5 ] ] ] ]

    const all = ([ value, ...children ]) =>
    [ value ] .concat (children .flatMap (all))

    console.log (all (tree))
    // [ 0, 1, 2, 3, 4, 5 ]





    really cool things






    const ranks =
    [ 'J', 'Q', 'K', 'A' ]

    const suits =
    [ '♡', '♢', '♤', '♧' ]

    console.log
    ( ranks .flatMap (r =>
    suits .flatMap (s =>
    [ [ r, s ] ]
    )
    )
    )

    // [ ['J','♡'], ['J','♢'], ['J','♤'], ['J','♧']
    // , ['Q','♡'], ['Q','♢'], ['Q','♤'], ['Q','♧']
    // , ['K','♡'], ['K','♢'], ['K','♤'], ['K','♧']
    // , ['A','♡'], ['A','♢'], ['A','♤'], ['A','♧']
    // ]








    share|improve this answer


















    • 1




      That is really nice, although of limited practical use until there’s Microsoft and Node support.
      – Mark Meyer
      Nov 11 at 6:39















    up vote
    4
    down vote













    I would recommend Array.prototype.flatMap






    const twice = x =>
    [ x, x ]

    console.log
    ( [ 'a', 'b', 'c' ] .flatMap (twice) // [ 'a', 'a', 'b', 'b', 'c', 'c' ]
    , [ 1, 2, 3, 4, 5 ] .flatMap (twice) // [ 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 ]
    )





    flatMap is useful for all kinds of things






    const tree =
    [ 0, [ 1 ], [ 2, [ 3 ], [ 4, [ 5 ] ] ] ]

    const all = ([ value, ...children ]) =>
    [ value ] .concat (children .flatMap (all))

    console.log (all (tree))
    // [ 0, 1, 2, 3, 4, 5 ]





    really cool things






    const ranks =
    [ 'J', 'Q', 'K', 'A' ]

    const suits =
    [ '♡', '♢', '♤', '♧' ]

    console.log
    ( ranks .flatMap (r =>
    suits .flatMap (s =>
    [ [ r, s ] ]
    )
    )
    )

    // [ ['J','♡'], ['J','♢'], ['J','♤'], ['J','♧']
    // , ['Q','♡'], ['Q','♢'], ['Q','♤'], ['Q','♧']
    // , ['K','♡'], ['K','♢'], ['K','♤'], ['K','♧']
    // , ['A','♡'], ['A','♢'], ['A','♤'], ['A','♧']
    // ]








    share|improve this answer


















    • 1




      That is really nice, although of limited practical use until there’s Microsoft and Node support.
      – Mark Meyer
      Nov 11 at 6:39













    up vote
    4
    down vote










    up vote
    4
    down vote









    I would recommend Array.prototype.flatMap






    const twice = x =>
    [ x, x ]

    console.log
    ( [ 'a', 'b', 'c' ] .flatMap (twice) // [ 'a', 'a', 'b', 'b', 'c', 'c' ]
    , [ 1, 2, 3, 4, 5 ] .flatMap (twice) // [ 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 ]
    )





    flatMap is useful for all kinds of things






    const tree =
    [ 0, [ 1 ], [ 2, [ 3 ], [ 4, [ 5 ] ] ] ]

    const all = ([ value, ...children ]) =>
    [ value ] .concat (children .flatMap (all))

    console.log (all (tree))
    // [ 0, 1, 2, 3, 4, 5 ]





    really cool things






    const ranks =
    [ 'J', 'Q', 'K', 'A' ]

    const suits =
    [ '♡', '♢', '♤', '♧' ]

    console.log
    ( ranks .flatMap (r =>
    suits .flatMap (s =>
    [ [ r, s ] ]
    )
    )
    )

    // [ ['J','♡'], ['J','♢'], ['J','♤'], ['J','♧']
    // , ['Q','♡'], ['Q','♢'], ['Q','♤'], ['Q','♧']
    // , ['K','♡'], ['K','♢'], ['K','♤'], ['K','♧']
    // , ['A','♡'], ['A','♢'], ['A','♤'], ['A','♧']
    // ]








    share|improve this answer














    I would recommend Array.prototype.flatMap






    const twice = x =>
    [ x, x ]

    console.log
    ( [ 'a', 'b', 'c' ] .flatMap (twice) // [ 'a', 'a', 'b', 'b', 'c', 'c' ]
    , [ 1, 2, 3, 4, 5 ] .flatMap (twice) // [ 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 ]
    )





    flatMap is useful for all kinds of things






    const tree =
    [ 0, [ 1 ], [ 2, [ 3 ], [ 4, [ 5 ] ] ] ]

    const all = ([ value, ...children ]) =>
    [ value ] .concat (children .flatMap (all))

    console.log (all (tree))
    // [ 0, 1, 2, 3, 4, 5 ]





    really cool things






    const ranks =
    [ 'J', 'Q', 'K', 'A' ]

    const suits =
    [ '♡', '♢', '♤', '♧' ]

    console.log
    ( ranks .flatMap (r =>
    suits .flatMap (s =>
    [ [ r, s ] ]
    )
    )
    )

    // [ ['J','♡'], ['J','♢'], ['J','♤'], ['J','♧']
    // , ['Q','♡'], ['Q','♢'], ['Q','♤'], ['Q','♧']
    // , ['K','♡'], ['K','♢'], ['K','♤'], ['K','♧']
    // , ['A','♡'], ['A','♢'], ['A','♤'], ['A','♧']
    // ]








    const twice = x =>
    [ x, x ]

    console.log
    ( [ 'a', 'b', 'c' ] .flatMap (twice) // [ 'a', 'a', 'b', 'b', 'c', 'c' ]
    , [ 1, 2, 3, 4, 5 ] .flatMap (twice) // [ 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 ]
    )





    const twice = x =>
    [ x, x ]

    console.log
    ( [ 'a', 'b', 'c' ] .flatMap (twice) // [ 'a', 'a', 'b', 'b', 'c', 'c' ]
    , [ 1, 2, 3, 4, 5 ] .flatMap (twice) // [ 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 ]
    )





    const tree =
    [ 0, [ 1 ], [ 2, [ 3 ], [ 4, [ 5 ] ] ] ]

    const all = ([ value, ...children ]) =>
    [ value ] .concat (children .flatMap (all))

    console.log (all (tree))
    // [ 0, 1, 2, 3, 4, 5 ]





    const tree =
    [ 0, [ 1 ], [ 2, [ 3 ], [ 4, [ 5 ] ] ] ]

    const all = ([ value, ...children ]) =>
    [ value ] .concat (children .flatMap (all))

    console.log (all (tree))
    // [ 0, 1, 2, 3, 4, 5 ]





    const ranks =
    [ 'J', 'Q', 'K', 'A' ]

    const suits =
    [ '♡', '♢', '♤', '♧' ]

    console.log
    ( ranks .flatMap (r =>
    suits .flatMap (s =>
    [ [ r, s ] ]
    )
    )
    )

    // [ ['J','♡'], ['J','♢'], ['J','♤'], ['J','♧']
    // , ['Q','♡'], ['Q','♢'], ['Q','♤'], ['Q','♧']
    // , ['K','♡'], ['K','♢'], ['K','♤'], ['K','♧']
    // , ['A','♡'], ['A','♢'], ['A','♤'], ['A','♧']
    // ]





    const ranks =
    [ 'J', 'Q', 'K', 'A' ]

    const suits =
    [ '♡', '♢', '♤', '♧' ]

    console.log
    ( ranks .flatMap (r =>
    suits .flatMap (s =>
    [ [ r, s ] ]
    )
    )
    )

    // [ ['J','♡'], ['J','♢'], ['J','♤'], ['J','♧']
    // , ['Q','♡'], ['Q','♢'], ['Q','♤'], ['Q','♧']
    // , ['K','♡'], ['K','♢'], ['K','♤'], ['K','♧']
    // , ['A','♡'], ['A','♢'], ['A','♤'], ['A','♧']
    // ]






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 11 at 2:37

























    answered Nov 11 at 2:09









    user633183

    66.7k21130172




    66.7k21130172







    • 1




      That is really nice, although of limited practical use until there’s Microsoft and Node support.
      – Mark Meyer
      Nov 11 at 6:39













    • 1




      That is really nice, although of limited practical use until there’s Microsoft and Node support.
      – Mark Meyer
      Nov 11 at 6:39








    1




    1




    That is really nice, although of limited practical use until there’s Microsoft and Node support.
    – Mark Meyer
    Nov 11 at 6:39





    That is really nice, although of limited practical use until there’s Microsoft and Node support.
    – Mark Meyer
    Nov 11 at 6:39











    up vote
    4
    down vote













    You can use the function reduce and concatenate the same object on each iteration.






    let array = ["a", "b", "c"],
    result = array.reduce((a, c) => a.concat(c, c), );

    console.log(result);

    .as-console-wrapper max-height: 100% !important; top: 0; 








    share|improve this answer






















    • Is Array.prototype.concat.call... really necessary? Couldn't this just be done by array.concat(array).sort()?
      – George Jempty
      Nov 11 at 1:12






    • 1




      Makes sense. There's still more than one way to do it. For instance by making a copy of the original array with slice
      – George Jempty
      Nov 11 at 1:14






    • 1




      How's array.concat(array) going to mutate the original? The docs say "This method does not change the existing arrays, but instead returns a new array."
      – slider
      Nov 11 at 1:16










    • Also this assumes the original array is sorted. What if the original is ['b', 'a', 'c']?
      – slider
      Nov 11 at 1:17






    • 1




      Well, with ['b', 'a', 'c'] this will result in ["a","a","b","b","c","c"] but the desired output may be ['b', 'b', 'a', 'a', 'c', 'c'] (I'm not sure though).
      – slider
      Nov 11 at 1:20














    up vote
    4
    down vote













    You can use the function reduce and concatenate the same object on each iteration.






    let array = ["a", "b", "c"],
    result = array.reduce((a, c) => a.concat(c, c), );

    console.log(result);

    .as-console-wrapper max-height: 100% !important; top: 0; 








    share|improve this answer






















    • Is Array.prototype.concat.call... really necessary? Couldn't this just be done by array.concat(array).sort()?
      – George Jempty
      Nov 11 at 1:12






    • 1




      Makes sense. There's still more than one way to do it. For instance by making a copy of the original array with slice
      – George Jempty
      Nov 11 at 1:14






    • 1




      How's array.concat(array) going to mutate the original? The docs say "This method does not change the existing arrays, but instead returns a new array."
      – slider
      Nov 11 at 1:16










    • Also this assumes the original array is sorted. What if the original is ['b', 'a', 'c']?
      – slider
      Nov 11 at 1:17






    • 1




      Well, with ['b', 'a', 'c'] this will result in ["a","a","b","b","c","c"] but the desired output may be ['b', 'b', 'a', 'a', 'c', 'c'] (I'm not sure though).
      – slider
      Nov 11 at 1:20












    up vote
    4
    down vote










    up vote
    4
    down vote









    You can use the function reduce and concatenate the same object on each iteration.






    let array = ["a", "b", "c"],
    result = array.reduce((a, c) => a.concat(c, c), );

    console.log(result);

    .as-console-wrapper max-height: 100% !important; top: 0; 








    share|improve this answer














    You can use the function reduce and concatenate the same object on each iteration.






    let array = ["a", "b", "c"],
    result = array.reduce((a, c) => a.concat(c, c), );

    console.log(result);

    .as-console-wrapper max-height: 100% !important; top: 0; 








    let array = ["a", "b", "c"],
    result = array.reduce((a, c) => a.concat(c, c), );

    console.log(result);

    .as-console-wrapper max-height: 100% !important; top: 0; 





    let array = ["a", "b", "c"],
    result = array.reduce((a, c) => a.concat(c, c), );

    console.log(result);

    .as-console-wrapper max-height: 100% !important; top: 0; 






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 11 at 2:47

























    answered Nov 11 at 1:09









    Ele

    22.3k42044




    22.3k42044











    • Is Array.prototype.concat.call... really necessary? Couldn't this just be done by array.concat(array).sort()?
      – George Jempty
      Nov 11 at 1:12






    • 1




      Makes sense. There's still more than one way to do it. For instance by making a copy of the original array with slice
      – George Jempty
      Nov 11 at 1:14






    • 1




      How's array.concat(array) going to mutate the original? The docs say "This method does not change the existing arrays, but instead returns a new array."
      – slider
      Nov 11 at 1:16










    • Also this assumes the original array is sorted. What if the original is ['b', 'a', 'c']?
      – slider
      Nov 11 at 1:17






    • 1




      Well, with ['b', 'a', 'c'] this will result in ["a","a","b","b","c","c"] but the desired output may be ['b', 'b', 'a', 'a', 'c', 'c'] (I'm not sure though).
      – slider
      Nov 11 at 1:20
















    • Is Array.prototype.concat.call... really necessary? Couldn't this just be done by array.concat(array).sort()?
      – George Jempty
      Nov 11 at 1:12






    • 1




      Makes sense. There's still more than one way to do it. For instance by making a copy of the original array with slice
      – George Jempty
      Nov 11 at 1:14






    • 1




      How's array.concat(array) going to mutate the original? The docs say "This method does not change the existing arrays, but instead returns a new array."
      – slider
      Nov 11 at 1:16










    • Also this assumes the original array is sorted. What if the original is ['b', 'a', 'c']?
      – slider
      Nov 11 at 1:17






    • 1




      Well, with ['b', 'a', 'c'] this will result in ["a","a","b","b","c","c"] but the desired output may be ['b', 'b', 'a', 'a', 'c', 'c'] (I'm not sure though).
      – slider
      Nov 11 at 1:20















    Is Array.prototype.concat.call... really necessary? Couldn't this just be done by array.concat(array).sort()?
    – George Jempty
    Nov 11 at 1:12




    Is Array.prototype.concat.call... really necessary? Couldn't this just be done by array.concat(array).sort()?
    – George Jempty
    Nov 11 at 1:12




    1




    1




    Makes sense. There's still more than one way to do it. For instance by making a copy of the original array with slice
    – George Jempty
    Nov 11 at 1:14




    Makes sense. There's still more than one way to do it. For instance by making a copy of the original array with slice
    – George Jempty
    Nov 11 at 1:14




    1




    1




    How's array.concat(array) going to mutate the original? The docs say "This method does not change the existing arrays, but instead returns a new array."
    – slider
    Nov 11 at 1:16




    How's array.concat(array) going to mutate the original? The docs say "This method does not change the existing arrays, but instead returns a new array."
    – slider
    Nov 11 at 1:16












    Also this assumes the original array is sorted. What if the original is ['b', 'a', 'c']?
    – slider
    Nov 11 at 1:17




    Also this assumes the original array is sorted. What if the original is ['b', 'a', 'c']?
    – slider
    Nov 11 at 1:17




    1




    1




    Well, with ['b', 'a', 'c'] this will result in ["a","a","b","b","c","c"] but the desired output may be ['b', 'b', 'a', 'a', 'c', 'c'] (I'm not sure though).
    – slider
    Nov 11 at 1:20




    Well, with ['b', 'a', 'c'] this will result in ["a","a","b","b","c","c"] but the desired output may be ['b', 'b', 'a', 'a', 'c', 'c'] (I'm not sure though).
    – slider
    Nov 11 at 1:20










    up vote
    2
    down vote













    You could just do this:



    var arr = ["a", "b", "c"];
    arr = arr.concat(arr).sort();


    This is one of the simplest methods to do what you are asking to do.






    share|improve this answer


























      up vote
      2
      down vote













      You could just do this:



      var arr = ["a", "b", "c"];
      arr = arr.concat(arr).sort();


      This is one of the simplest methods to do what you are asking to do.






      share|improve this answer
























        up vote
        2
        down vote










        up vote
        2
        down vote









        You could just do this:



        var arr = ["a", "b", "c"];
        arr = arr.concat(arr).sort();


        This is one of the simplest methods to do what you are asking to do.






        share|improve this answer














        You could just do this:



        var arr = ["a", "b", "c"];
        arr = arr.concat(arr).sort();


        This is one of the simplest methods to do what you are asking to do.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 12 at 2:25

























        answered Nov 11 at 1:11









        Jack Bashford

        3,31131031




        3,31131031



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53244954%2fduplicating-an-arrays-elements-using-functional-programming%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            How to read a connectionString WITH PROVIDER in .NET Core?

            Node.js Script on GitHub Pages or Amazon S3

            Museum of Modern and Contemporary Art of Trento and Rovereto