1

I would like to take an array of arrays and concatenate the next item with the last array in the array.

var array = [
  ["thomas"], 
  ["jane"],
  ["harry"],
]

array = processArray(array);

console.log(array);

[
  ["thomas"],
  ["thomas", "jane"],
  ["thomas", "jane", "harry"],
]

Whats a good way to do this? Before I dive into it I was wondering if there was a simple way using underscore.

var processArray = function(grouped){
  var prev = false;
  var map = _.map(grouped, function(value, key) {
    if (prev) value.concat(grouped[prev]);
    prev = key;
    var temp = {};
    temp[key] = value;
    return temp;
  });
  return _.extend.apply(null, map);
}
Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
ThomasReggi
  • 55,053
  • 85
  • 237
  • 424
  • 1
    [Please don't ask these types of questions](http://meta.stackexchange.com/questions/144500/add-a-do-not-ask-canihaztehcodez-questions-admonition-to-the-faq) – Anonymous May 27 '14 at 22:44
  • 1
    Show us the code you've been working on to do this, and we'll help you get it working. You know the way it works here. :) – Jonathan M May 27 '14 at 22:45
  • 1
    Big difference between asking for code, and reinventing the wheel. If a resource or any help at all can be offered I'd take it. – ThomasReggi May 27 '14 at 22:46
  • But this isn't a wheel. We just want to see what you've tried. Tried looping? Tried `concat`? – elclanrs May 27 '14 at 22:49
  • Almighty, I posted some code, it doesn't really abide by the example because all my arrays are nested within objects. – ThomasReggi May 27 '14 at 23:12
  • I really wanted to just get some thoughts down and out of my head, when constructing a function like this it's good to see input / output. I realize it's in poor taste to just request code. But I thought perhaps it could spare me some time if there was a magical combination of underscore functions that did the trick. Apologies and thanks for the honest feedback! – ThomasReggi May 27 '14 at 23:14
  • I think what people are getting at is if you don't have broken code, you may wanna try http://codereview.stackexchange.com/ – 13ruce1337 May 27 '14 at 23:40

3 Answers3

1

Given that

var array = [
  ["thomas"], 
  ["jane"],
  ["harry"],
]

you can simply do

var A=[];
array = array.map(function(o,i){
    return A.concat.apply(A, array.slice(0,i+1))
});

See this SO post on details on concat usage.

Community
  • 1
  • 1
Etheryte
  • 24,589
  • 11
  • 71
  • 116
0

one simple way is to use map and slice to make new arrays in each return:

 [
  ["thomas"], 
  ["jane"],
  ["harry"],
]
.map(function(a){return a[0];})  // flatten sub-array to just primitive value
.map(function(a,b,c){return c.slice(0,b+1)}); // slice all primitive values by position

/* == 
[
  ["thomas"],
  ["thomas", "jane"],
  ["thomas", "jane", "harry"],
]
*/

EDIT:

Nit shows a nice use of apply to combine my step one and two. that pattern using inline like my code would look like this (again, thanks to nit):

[
  ["thomas"], 
  ["jane"],
  ["harry"],
].map(function(o,i,a){
    return this.concat.apply(this, a.slice(0,i+1));
}, []);

I really like this version best of all (so far): it works, is one line, has no variables or closure, and makes smart use of built-ins.

dandavis
  • 16,370
  • 5
  • 40
  • 36
  • @RobG: i tried that, but it yeilds an array of arrays of array, or an array of strings, when the question illustrated an array of arrays of strings... – dandavis May 28 '14 at 01:02
  • @RobG: still not so simple i'm afraid, though i respect your tenacity. your comment's code will leave the thirds element as [""thomas,jane,harry"], not ["thomas", "jane", "harry"]. go with nit's solution used inline. hmm, i'll whip that up since people around here are superstitious about _this_ in array methods... – dandavis May 28 '14 at 19:34
  • @danddavis—Ok, finally got there. I don't care whether you use it, just happy to find *reduce* does what I thought :-) `arr.reduce(function(x,v,i){return x.push(i? x[i-1].concat(v) : v) && x},[])` – RobG May 29 '14 at 02:35
0

What you’re looking for seems to be a specific case of the more general reductions, which returns the intermediate results of reduce. The original Clojure version can be reimplemented in JavaScript:

function reductions(xs, f, init) {
  if(typeof(init) === "undefined") {
    return reductions(_.rest(xs), f, _.first(xs))
  }
  if(xs.length === 0) return [init]

  var y = f(init, _.first(xs))
  return [init].concat(reductions(_.rest(xs), f, y))
}

And used just like JavaScript’s own reduce:

var array = ["thomas", "jane", "harry"]
reductions(array, function(xs, x) { return xs.concat(x) }, [])
//=> [[] ["thomas"], ["thomas", "jane"], ["thomas", "jane", "harry"]]

Of course you can easily remove the initial [] with _.rest.

Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214