Create multidimensional array in a loop with auto index

纵然是瞬间 提交于 2020-06-17 01:00:27

问题


I'd like to create a multidimensional array using a loop in jQuery/JS. Is it possible to use the next available key instead of setting it manually?

jsonFromPhp contains something like this:

0 {first_name: "Tom", last_name: "Smith", location: "London"}
1 {first_name: "Max", last_name: "Muster", location: "Zurich"}
2 {first_name: "Joanne", last_name: "Kate", location: "London"}
...

Here is the loop:

jsonFromPhp.forEach((row, i) => {
    if (row['location'] == 'London') {
        firstKey = 0;
    } else {
        firstKey = 1;
    }

    row.forEach((singleData, n) => {
        pushedArray[firstKey][] = singleData[n]; // doesn't work, I have set the index manually (with i for example). But then I have an array like 0, 2, 5 etc. and I need 0, 1, 2
    });
});

Expected Result:
0 Array (1)
    0 ["Tom", "Smith", "London"] (3)
    1 ["Joanne", "Kate", "London"] (3)
    ...
1 Array (1)
    0 ["Max", "Muster", "Zurich"] (3)
    ...

and not (if I set pushedArray[firstKey][i])

0 Array (1)
    0 ["Tom", "Smith", "London"] (3)
    2 ["Joanne", "Kate", "London"] (3)
    ...
1 Array (1)
    1 ["Max", "Muster", "Zurich"] (3)
    ...

or

0 Array (1)
    0 ["Tom", "Smith", "London", "Joanne", "Kate", "London"] (6)
1 Array (1)
    1 ["Max", "Muster", "Zurich"] (3)
    ...

回答1:


use the next available key

To generate array indices automatically, the easiest way is with

arr.push(value)

this is the same as

arr[arr.length] = value

The issue in this question is for multi-dimensional array to ensure you are "pushing" into the correct dimension.

In this case, the 1st dimension ("london") is always 2 long, so we can simplify this by creating the array up-front:

var arr = [[],[]];

which creates an array with 2 entries, both of which are themselves empty arrays (2 dimensions).

The code then determines whether to use 0 or 1, that's fine - the next dimension is then for each row / object in the source and under that is where the data goes, giving:

var source = [
{first_name: "Tom", last_name: "Smith", location: "London"},
{first_name: "Max", last_name: "Muster", location: "Zurich"},
{first_name: "Joanne", last_name: "Kate", location: "London"}
];

// create 1st dimension (arr[0], arr[1]) initially
var arr=[[],[]];

// loop through each source row
source.forEach((row, i) => {
    if (row['location'] == 'London') {
        firstKey = 0;
    } else {
        firstKey = 1;
    }
    
    // add a subdimension for this row
    var rowArr = [];
    for(var k in row)
    {
        // add the properties into the subdimension
        rowArr.push(row[k]); 
    }
    
    // add the object->array into the 0/1 top-level array
    // using "the next available index"
    arr[firstKey].push(rowArr);
        
});
console.log(arr);

This can or course be substantially reduced (eg using .map and ?: for location), but this keeps the closest to your original code, changing only the parts relevant to the question.


Reducing your code using .forEach

Using object to array and the same principle of creating the base array up-front you can use ?: to reduce the location index:

firstKey = row['location'] == 'London' ? 0 : 1

We can reduce your code to a one-liner (split for clarity):

var source = [
{first_name: "Tom", last_name: "Smith", location: "London"},
{first_name: "Max", last_name: "Muster", location: "Zurich"},
{first_name: "Joanne", last_name: "Kate", location: "London"}
];

var arr = [[],[]];

source.forEach((row) => 
    arr[row['location'] == 'London' ? 0 : 1].push(
        Object.keys(row).map(
            (key) => row[key]
        )
    )
);

console.log(arr)



回答2:


This solution will work for more than 2 locations as well as no need to care about what values come for location from backend.

const arr = [{
  first_name: "Tom",
  last_name: "Smith",
  location: "London"
}, {
  first_name: "Max",
  last_name: "Muster",
  location: "Zurich"
}, {
  first_name: "Joanne",
  last_name: "Kate",
  location: "London"
}]
const result = {};

arr.map(item => {
  result[item.location] = [];
  return item;
}).map(item => {
  result[item.location].push(Object.values(item));
});

let res2 = [];
Object.keys(result).forEach((key, index) => {
  res2[index] = result[key]
});
console.log(res2)


来源:https://stackoverflow.com/questions/61930789/create-multidimensional-array-in-a-loop-with-auto-index

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!