0

I am trying to convert [arr1, arr2, arr3], where arr1, arr2 and arr3 are arrays containing the values 1, 2 and 3 respectively, to the more simplified form [1, 2, 3].

In particular, I am getting JSON data through an API and pushing values and creating and array to store them, like this:

let parentFolderids = []; // store their names within a local array
for(let i = 0; i < response.data.data.length; i++) {
    //const object = response.data.data[i];
    //console.log(object.parentIds[0])
    parentFolderids.push(response.data.data[i].parentIds);
}

Let's say the result of this is parentFolderids being, for example, [ [12], [33], [22] ].

I want to convert it to simply [12, 33, 22]. How should I do it?

Ilmari Karonen
  • 49,047
  • 9
  • 93
  • 153
  • Can you use `array.flat()` or `[].concat(...array)`? I'm not sure I follow all of the details about the API and so forth. This question could just be "given an array `x`, how do I get `y`? and here's what I tried...", right? Can you show the original JSON response? Thanks. – ggorlen Sep 07 '19 at 15:56
  • I think i solve it just by adding .toString() parentFolderids.push(response.data.data[i].parentIds.toString()); – Cobra Commander Sep 07 '19 at 15:57
  • thanks ggorlen for tring to help :) – Cobra Commander Sep 07 '19 at 15:58

1 Answers1

1

Here's a bunch of different ways:

Using .map() (extracts only first element of each inner array; works on all modern browsers):

const array = [[12], [33], [22], [77, 88, 99]];
const flat = array.map( x => x[0] );
console.log(flat);

Using .flatMap() (extracts all elements of each inner array; not supported on IE or Edge as of this writing*, polyfills available):

const array = [[12], [33], [22], [77, 88, 99]];
const flat = array.flatMap( x => x );
console.log(flat);

Using .flat() (same support limitations as above):

const array = [[12], [33], [22], [77, 88, 99]];
const flat = array.flat(1);
console.log(flat);

Using .concat() and spread syntax (also not supported on IE / Edge*, polyfills not possible):

const array = [[12], [33], [22], [77, 88, 99]];
const flat = [].concat(...array);
console.log(flat);

Using for...of loop and .push() (extracts only first element, works on every modern browser but not on IE):

const array = [[12], [33], [22], [77, 88, 99]];
const flat = [];
for (const x of array) {
    flat.push( x[0] );
}
console.log(flat);

Using a plain old for(;;) loop and .push() (extracts only first element, works everywhere):

const array = [[12], [33], [22], [77, 88, 99]];
const flat = [];
for (let i = 0; i < array.length; i++) {
    flat.push( array[i][0] );
}
console.log(flat);

Using a plain old for(;;) loop with in-place modification (extracts only first element, modifies original array, works everywhere):

const array = [[12], [33], [22], [77, 88, 99]];
for (let i = 0; i < array.length; i++) {
    array[i] = array[i][0];
}
console.log(array);

I'm sure this is not an exhaustive list.


Ps. For your example code above, you might as well extract the parent IDs directly into a flat array, like this:

const parentFolderIds = response.data.data.map( x => x.parentIds[0] );

or (if you'd like all the parent IDs for each item, in case there are several):

const parentFolderIds = response.data.data.flatMap( x => x.parentIds );

or (if you prefer an explicit loop):

const parentFolderIds = [];
for (const x of response.data.data) {
    parentFolderIds.push( x.parentIds[0] );
}

or even just:

const data = response.data.data, parentFolderIds = [];
for (let i = 0; i < data.length; i++) {
    parentFolderIds.push( data[i].parentIds[0] );
}

In any case, there's no point in first extracting them into a nested array and then flattening it, at least not unless you also need the nested array for something else.


*) The Edge 78.0 dev build seems to handle all of these fine, though — as one would expect, given that it's using the same JS engine as Chrome.

Ilmari Karonen
  • 49,047
  • 9
  • 93
  • 153
  • "polyfill" of `[].concat(...a)` spread syntax is `Array.prototype.concat.apply([], a)` – Mulan Sep 07 '19 at 17:25
  • any solution touching `x[0]` where `x` is an array must also check `x.length > 0` otherwise `undefined` leaks into your program – Mulan Sep 07 '19 at 17:26
  • @user633183: The OP specified that each inner array has exactly one element. If that assumption is _not_ actually always true, they will likely have bigger issues than the presence of a few `undefined` values in the array. (In particular, the various solutions I gave above will no longer all be equivalent, and the OP needs to decide how they actually want to handle cases where the inner array has more or less than one element. In some cases an `undefined` placeholder element might actually be exactly what's needed, but it's impossible to say if that's the case here without more context.) – Ilmari Karonen Sep 07 '19 at 17:32
  • i'm not saying your answer is wrong, i'm only alerting users of these programs that they will produce `undefined` in certain circumstances ^^ – Mulan Sep 07 '19 at 17:39
  • for consistency, i think `for (let x of array) ...` should be `for (const x of array) ...`. ie, use `let` only when the variable needs to be mutable, like in your `let i ... i++` examples. – Mulan Sep 07 '19 at 17:42