1

I have an array [1,2,3,4,5,6] and a separator '~' and I want to joint them into a new array with '~' being the separator.

I'd like the output to be [1,'~', 2,'~', 3,'~', 4,'~', 5,'~', 6].

Using Lodash I got something like:

var my_array = [1,2,3,4,5,6]
var separator = '~'
_.flatten(_.zip(my_array, new Array(my_array.length).fill(separator)))

But this feels ugly and I'm sure there is a better way.

EDIT: Even though the array above has ints I'd like this to work for any type of object.

Agam Rafaeli
  • 5,291
  • 3
  • 17
  • 21
  • 3
    Why not just a nice simple loop? – T.J. Crowder Feb 28 '17 at 11:46
  • A nice simple loop will do the trick, but will mandate a manual `-1` in the length. Was looking for something a little more pretty. – Agam Rafaeli Feb 28 '17 at 11:48
  • *"...but will mandate a manual -1 in the length..."* Huh? – T.J. Crowder Feb 28 '17 at 11:50
  • `join` is an ugly operation to implement because it has an inherent break of the symmetry. – Aur Saraf Feb 28 '17 at 11:50
  • @AurSaraf what do you mean by break of the symmetry? – Agam Rafaeli Feb 28 '17 at 11:51
  • @T.J.Crowder in order for this to be actually simple the loop will have to run for `my_array.length - 1` times. No? – Agam Rafaeli Feb 28 '17 at 11:52
  • 1
    The question has been closed, but a single line ES6 would be: `var r = Array.from({ length: (a.length * 2) - 1 }, (v, i) => i % 2 ? s : a[i/2] );` Where `a` is your array and `s` is your "~". Codepen: http://codepen.io/cjke/pen/pejPOQ?editors=0010 – Chris Feb 28 '17 at 14:14
  • I'm a bit bored - here is an even shorter one: `var r = a.reduce((c, v) => [...c, v, s], []).slice(0, -1)` Codepen: http://codepen.io/cjke/pen/WpQPKz?editors=0010 – Chris Mar 01 '17 at 03:20
  • @AgamRafaeli I mean it does something to all of the array values *but one*. – Aur Saraf Mar 09 '17 at 08:13

7 Answers7

8

Why not in pue Javascript:

Minor Update: to account for values greater then 9

  • first join it to a string my_array.join("~")
  • then split every char .split(/\b/gi)

var my_array = [1,2,3,4,5,6,10,11]
var separator = '~'

console.info(my_array.join("~").split(/\b/gi));

Update (even if closed):

In Regard to point, other Objects. This should work, even if not a one-liner.

var myArray = [1,2,3,45,6,10,new Date()];

var newArray = myArray.reduce((p,n)=>{ 
  if(p.length){
    p.push("~");
  }
  p.push(n);
  return p;
},[]);

console.info(newArray)
winner_joiner
  • 6,663
  • 4
  • 36
  • 55
5

Nice simple forEach without a dozen temporary arrays, etc.:

var my_array = [1,2,3,4,5,6];
var result = [my_array[0]];
my_array.forEach(function(entry, index) {
  if (index > 0) {
    result.push("~", entry);
  }
});
console.log(result);

Or you can get rid of the if with a single temporary array:

var my_array = [1,2,3,4,5,6];
var result = [my_array[0]];
my_array.slice(1).forEach(function(entry, index) {
  result.push("~", entry);
});
console.log(result);
T.J. Crowder
  • 959,406
  • 173
  • 1,780
  • 1,769
3

Just throwing my hat in:

arr.map(x => [x, '~']).reduce((p, c) => p.concat(c));

This isn't very hacky, it maps every element into two elements and concats them together, it is pretty easy to generalize:

const intercalate = (arr, sep) => arr.map(x => [x, sep])
                                     .reduce((p, c) => p.concat(c))
                                     .slice(0, -1);

Or with a single reduce:

const intercalate = (arr, sep) => arr.reduce((p, c) => p.concat(c, sep)).slice(0, -1);
Benjamin Gruenbaum
  • 260,410
  • 85
  • 489
  • 489
2

Here is an option using forEach -

var a = [1,2,3]
var sep = '~'
var b = []
a.forEach(function(x) { b.push(x, sep) })
b.pop() // remove the last `~`
Lix
  • 46,307
  • 10
  • 97
  • 126
1

Using _.flatMap,

var my_array = [1,2,3,4,5,6];
var separator = '~';
console.log(_.flatMap(my_array, function( v ){ return [v,separator] }).slice(0,-1));

Update:

Ensure trailing ~ is removed.

zahirdhada
  • 395
  • 3
  • 14
0

You could use Array#reduce and concat a tilde if necessary.

var array = [1, 2, 3, 4, 5, 6],
    result = array.reduce(function (r, a, i) {
        return r.concat(i ? '~' : [], a);
    }, []);
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Anosther proposal with Array#forEach

var array = [1, 2, 3, 4, 5, 6],
    result = [];

array.forEach(function (a) {
   result.push(a, '~');
});

result.length--;
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 351,820
  • 24
  • 303
  • 358
0

Using a traditional for loop

var nums = [1,2,3,4,5,6];
var dash = '~';

var res = [];
for (var i=0; i<nums.length; i++){
  res.push(nums[i]);
  res.push(dash);
}
res.pop();

console.log(res);
Idan
  • 5,079
  • 7
  • 34
  • 48