使用javascript

时间:2019-08-14 07:30:35

标签: javascript arrays object reduce

我有这样复杂的json:

const lstCountry = {
   "cols": ["id", "countryName", "area"],
   "data": [
       ["1", "Russia", "17098242"],
       ["2", "Canada", "9970610"],
       ["3", "China", "9640821"],
       ["4", "United States", "9629091"],
       ["5", "Brazil", "8514877"],
       ["6", "Australia", "7741220"],
       ["7", "India", "3287263"],
       ["8", "Argentina", "2780400"],
       ["9", "Kazakhstan", "2724900"],
       ["10", "Sudan", "2505813"]
    ]
};

现在我想转换成简单的数组作为这样的输出:

const countryList = [
    { "id": "1", "countryName": "Russia", "area": "17098242" },
    { "id": "2", "countryName": "Canada", "area": "9970610" },
    { "id": "3", "countryName": "China", "area": "9640821" },
    { "id": "4", "countryName": "United States", "area": "9629091" },
    { "id": "5", "countryName": "Brazil", "area": "8514877" },
    { "id": "6", "countryName": "Australia", "area": "7741220" },
    { "id": "7", "countryName": "India", "area": "3287263" },
    { "id": "8", "countryName": "Argentina", "area": "2780400" },
    { "id": "9", "countryName": "Kazakhstan", "area": "2724900" },
    { "id": "10", "countryName": "Sudan", "area": "2505813" },
];

我已经在下面尝试过,但是使用index作为键得到了输出,所以我该如何使用cols array as a key和另一个data array as a value转换键,并使用这些键和值的组合生成自己的数组。 / p>

或者有没有简单的方法可以将其存档,例如使用地图,reduce?

已经尝试过:

let mainData = [];
for (let i = 1; i < Object.keys(data).length; i++) {
    const eleData = data[Object.keys(data)[i]];
    for (let j = 0; j < eleData.length; j++) {
        const element = Object.assign({}, eleData[j]);
        mainData.push(element);
    };            
};
console.log('mainData:', mainData)

尝试过的函数输出:

const mainData = [
    { "0": "1", "1": "Russia", "2": "17098242" },
    { "0": "2", "1": "Canada", "2": "9970610" },
    { "0": "3", "1": "China", "2": "9640821" },
    { "0": "4", "1": "United States", "2": "9629091" },
    { "0": "5", "1": "Brazil", "2": "8514877" },
    { "0": "6", "1": "Australia", "2": "7741220" },
    { "0": "7", "1": "India", "2": "3287263" },
    { "0": "8", "1": "Argentina", "2": "2780400" },
    { "0": "9", "1": "Kazakhstan", "2": "2724900" },
    { "0": "10", "1": "Sudan", "2": "2505813" },
];

6 个答案:

答案 0 :(得分:4)

您可以简单地在每个对象上map,并使用reduce创建与每个列相关的每个对象:

const lstCountry = {
   "cols": ["id", "countryName", "area"],
   "data": [
       ["1", "Russia", "17098242"],
       ["2", "Canada", "9970610"],
       ["3", "China", "9640821"],
       ["4", "United States", "9629091"],
       ["5", "Brazil", "8514877"],
       ["6", "Australia", "7741220"],
       ["7", "India", "3287263"],
       ["8", "Argentina", "2780400"],
       ["9", "Kazakhstan", "2724900"],
       ["10", "Sudan", "2505813"]
    ]
};

const { cols, data } = lstCountry

console.log(data.map(arr => arr.reduce((a, e, i) => (a[cols[i]] = e, a), {})))

编辑:功能上:

const fn = (cols, data) => data.map(arr => arr.reduce((a, e, i) => (a[cols[i]] = e, a), {}))

console.log(fn(['test'], [[1],[2],[3],[4]]))
console.log(fn(['test', 'true'], [[1,1],[2,1],[3,1],[4,1]]))

根据此JSPerf,该解决方案最注重性能,因为只有两个循环,而不是三个循环:

JSPerf

答案 1 :(得分:2)

您可以映射对象的条目并构建新对象。

var lstCountry = { cols: ["id", "countryName", "area"], data: [["1", "Russia", "17098242"], ["2", "Canada", "9970610"], ["3", "China", "9640821"], ["4", "United States", "9629091"], ["5", "Brazil", "8514877"], ["6", "Australia", "7741220"], ["7", "India", "3287263"], ["8", "Argentina", "2780400"], ["9", "Kazakhstan", "2724900"], ["10", "Sudan", "2505813"]] },
    result = lstCountry.data.map(a =>
        Object.fromEntries(a.map((v, i) => [lstCountry.cols[i], v])));

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

带有Object.assign的EDGE版本。

const getObjects = (keys, data) => data.map(a =>
        Object.assign(...a.map((v, i) => ({ [keys[i]]: v }))));

var lstCountry = { cols: ["id", "countryName", "area"], data: [["1", "Russia", "17098242"], ["2", "Canada", "9970610"], ["3", "China", "9640821"], ["4", "United States", "9629091"], ["5", "Brazil", "8514877"], ["6", "Australia", "7741220"], ["7", "India", "3287263"], ["8", "Argentina", "2780400"], ["9", "Kazakhstan", "2724900"], ["10", "Sudan", "2505813"]] },
    result = getObjects(lstCountry.cols, lstCountry.data);

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

答案 2 :(得分:2)

一个选项是使用map遍历data数组。使用reduce构造对象。

const lstCountry = {
  "cols": ["id", "countryName", "area"],
  "data": [
    ["1", "Russia", "17098242"],
    ["2", "Canada", "9970610"],
    ["3", "China", "9640821"],
    ["4", "United States", "9629091"],
    ["5", "Brazil", "8514877"],
    ["6", "Australia", "7741220"],
    ["7", "India", "3287263"],
    ["8", "Argentina", "2780400"],
    ["9", "Kazakhstan", "2724900"],
    ["10", "Sudan", "2505813"]
  ]
};

const rows = lstCountry['data'];
const cols = lstCountry['cols'];

const countryList = rows.map(o => o.reduce((c, v, i) => Object.assign(c, {[cols[i]]: v}), {}));

console.log(countryList);

答案 3 :(得分:2)

映射.data属性,并根据Object.fromEntries中的键,使用.data将每个cols子数组转换为一个对象:

const lstCountry = {
   "cols": ["id", "countryName", "area"],
   "data": [
       ["1", "Russia", "17098242"],
       ["2", "Canada", "9970610"],
       ["3", "China", "9640821"],
       ["4", "United States", "9629091"],
       ["5", "Brazil", "8514877"],
       ["6", "Australia", "7741220"],
       ["7", "India", "3287263"],
       ["8", "Argentina", "2780400"],
       ["9", "Kazakhstan", "2724900"],
       ["10", "Sudan", "2505813"]
    ]
};

const countryList = lstCountry.data.map(
  vals => Object.fromEntries(
    vals.map((val, i) => [lstCountry.cols[i], val])
  )
);
console.log(countryList);

对于lstCountry对象中的动态属性名称,只需使用括号符号即可:

const lstCountry = {
   "cols": ["id", "countryName", "area"],
   "data": [
       ["1", "Russia", "17098242"],
       ["2", "Canada", "9970610"],
       ["3", "China", "9640821"],
       ["4", "United States", "9629091"],
       ["5", "Brazil", "8514877"],
       ["6", "Australia", "7741220"],
       ["7", "India", "3287263"],
       ["8", "Argentina", "2780400"],
       ["9", "Kazakhstan", "2724900"],
       ["10", "Sudan", "2505813"]
    ]
};

const keyProp = 'cols';
const valProp = 'data';

const countryList = lstCountry[valProp].map(
  vals => Object.fromEntries(
    vals.map((val, i) => [lstCountry[keyProp][i], val])
  )
);
console.log(countryList);

答案 4 :(得分:0)

mapObject.fromEntries一起使用非常简单:

const lstCountry = {"cols":["id","countryName","area"],"data":[["1","Russia","17098242"],["2","Canada","9970610"],["3","China","9640821"],["4","United States","9629091"],["5","Brazil","8514877"],["6","Australia","7741220"],["7","India","3287263"],["8","Argentina","2780400"],["9","Kazakhstan","2724900"],["10","Sudan","2505813"]]};

const countryList = lstCountry.data.map(e => Object.fromEntries(lstCountry.cols.map((f, i) => [f, e[i]])));

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

答案 5 :(得分:-1)

您可以使用Array#mapArray#reduce来做到这一点。

此解决方案假定colsdata中每一行的长度都相同。

const countries = {
   "cols": ["id", "countryName", "area"],
   "data": [
       ["1", "Russia", "17098242"],
       ["2", "Canada", "9970610"],
       ["3", "China", "9640821"],
       ["4", "United States", "9629091"],
       ["5", "Brazil", "8514877"],
       ["6", "Australia", "7741220"],
       ["7", "India", "3287263"],
       ["8", "Argentina", "2780400"],
       ["9", "Kazakhstan", "2724900"],
       ["10", "Sudan", "2505813"]
    ]
};

const res = countries.data.map(arr=>{
  return countries.cols.reduce((a,c,i)=>{
    return {[c]:arr[i], ...a}
  },{})
});

console.log(res);