3

I have multiple 2 dimensional arrays that I would like to concat into a single 2 dimensional array:

var data = [
  [["x"], ["value1"], ["value2"], ["valu3"]],
  [["data1"], [0], [1], [2]],
  [["data2"], [2], [1], [0]]
];

wanted result:

var result = [
  ["x", "data1", "data2"],
  ["value1", 0, 2],
  ["value2", 1, 1],
  ["value3", 2, 0]
];

So far I am try to zip and concat using apply but I can't have the result I want:

var data = [
  [["x"], ["value1"], ["value2"], ["valu3"]],
  [["data1"], [0], [1], [2]],
  [["data2"], [2], [1], [0]]
];

var result = _.zipWith.apply(_, _.concat(data))

console.log(result)
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>

4
  • please add the wanted result. Commented Sep 27, 2018 at 15:11
  • @Nina Scholz he did in the snippet behind the variable result Commented Sep 27, 2018 at 15:13
  • The wanted result is still a multi-dimensional array... Commented Sep 27, 2018 at 15:13
  • Adriani: sorry there was a typo in my question Commented Sep 27, 2018 at 15:15

5 Answers 5

3

What about using regular ES6 javascript ? :)

const data = [
  [
    ['x'],
    ['value1'],
    ['value2'],
    ['valu3'],
  ],
  [
    ['data1'],
    [0],
    [1],
    [2],
  ],
  [
    ['data2'],
    [2],
    [1],
    [0],
  ],
];

const ret = data.map(x => x.reduce((tmp, y) => [
  ...tmp,
  ...y,
], []));

console.log(ret);


And in ES5 as asked for

var data = [
  [
    ['x'],
    ['value1'],
    ['value2'],
    ['valu3'],
  ],
  [
    ['data1'],
    [0],
    [1],
    [2],
  ],
  [
    ['data2'],
    [2],
    [1],
    [0],
  ],
];

var result = [];

for (let i = 0; i < data.length; i += 1) {
  var oneArray = [];

  for (let j = 0; j < data[i].length; j += 1) {
    for (let k = 0; k < data[i][j].length; k += 1) {
      oneArray.push(data[i][j][k]);
    }
  }

  result.push(oneArray);
}

console.log(result);

Sign up to request clarification or add additional context in comments.

4 Comments

@BelowtheRadar I've edited my post, hopes that's what you are looking for :)
Thanks a lot for the ES5 answer. I still have to support IE11 in my organization... :/
@BelowtheRadar I feel so sorry for you right now :<. Good luck!
I feel ashame, this is not the result I was looking for. There was an error in my wanted result in the question...
2

Using lodash transposing the matrix is as simple as this:

_.zipWith(...data, _.concat)

var data = [
  [["x"], ["value1"], ["value2"], ["valu3"]],
  [["data1"], [0], [1], [2]],
  [["data2"], [2], [1], [0]]
]
var res = _.zipWith(...data, _.concat);

console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

And also in Vanilla JS this is as simple as this

data[0].map((_,i)=>data.map(r=>r[i][0]))

var data = [
  [["x"], ["value1"], ["value2"], ["valu3"]],
  [["data1"], [0], [1], [2]],
  [["data2"], [2], [1], [0]]
];

var res = data[0].map((_,i)=>data.map(r=>r[i][0]));

console.log(res);

Note: You don't even need the _.concat and only _.zip would work (without 2nd argument) if your each rows were not nested, in your data rows are not [A, B, C, ...]. your rows are [[A], [B], [C], ...] but in output you need simple array for rows, so the _concat is used to make them simple array for each resultant row. Similarly in plain JS version the [0] in r[i][0] is needed because we have a nested level data in each row, otherwise (for simple row as input) it could have been r[i]

2 Comments

Can you add a working snippet with the data in the question? Then I'll accept your answer.
Here I have added working snippet in the answer with your data (provided in question). However, I haven't asked you to accept my answer, you should accept the best solution (whichever is) in order to help the community and users.
2

You could transpose the matrix.

var data = [[["x"], ["value1"], ["value2"], ["valu3"]], [["data1"], [0], [1], [2]], [["data2"], [2], [1], [0]]],
    result = data
        .reduce((r, a) => a.map(([v], i) => (r[i] || []).concat(v)), []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

ES5

var data = [[["x"], ["value1"], ["value2"], ["valu3"]], [["data1"], [0], [1], [2]], [["data2"], [2], [1], [0]]],
    result = data.reduce(function (r, a) {
          return a.map(function (v, i) {
              return (r[i] || []).concat(v);
          });
    }, []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

2

Concise solution with the use of ES6 destructuring and lodash _.zip, _.map & _.flatten:

var data = [[["x"], ["value1"], ["value2"], ["value3"]], [["data1"], [0], [1], [2]], [["data2"], [2], [1], [0]]]
    
var result = _.zip(..._.map(data, _.flatten))

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

Comments

1

What you want is called flatten. Lodash has 3 versions of that function.

const result = _.zip.apply(null, data).map(_.flatten)

5 Comments

sorry that's not the result I want
@BelowtheRadar exactly the same as wanted result repl.it/repls/KindheartedDetailedSpools
Look carefully at the wanted result in the question
@BelowtheRadar added zip
Thank you! That's the solution I was looking for!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.