Javascript:如何从另一个数组创建具有'x'个属性的数组?

时间:2019-05-07 03:21:56

标签: javascript arrays

我想转换以下数组

[{
   0-1s: 6,
   1-2s: 2,
   country: "us"
}, {
   0-1s: 1,
   1-2s: 4,
   country: "ja"
}, {
   0-1s: 3,
   1-2s: 9,
   country: "ca"
}]

进入这样的数组:

[{
   time: "0-1s",
   us: 6,
   ja: 1,
   ca: 3
},{
   time: "1-2s",
   us: 2,
   ja: 4,
   ca: 9
}]

这个想法是要轮换我的数组,使Country字段成为一个新属性,并且每个国家花费的时间都是水桶,所以无论有多少国家,我的数组中都只有2个元素(与Property一样多的国家) )这只是一个例子,我有40多个国家/地区。但是,我无法弄清楚如何在计划JavaScript中实现这种新的数据结构。

我应该如何处理?

3 个答案:

答案 0 :(得分:3)

您可以使用reduce将它们分组为一个以"0-1s""1-2s"为键的累加器对象。然后使用Object.values()获取值数组:

const input = [{
   "0-1s": 6,
   "1-2s": 2,
   country: "us"
}, {
   "0-1s": 1,
   "1-2s": 4,
   country: "ja"
}, {
   "0-1s": 3,
   "1-2s": 9,
   country: "ca"
}]

const grouped = input.reduce((r, o) => {
  r["0-1s"] = r["0-1s"] || { time: "0-1s" };
  r["1-2s"] = r["1-2s"] || { time: "1-2s" };
  
  r["0-1s"][o.country] = o["0-1s"]
  r["1-2s"][o.country] = o["1-2s"]
  
  return r;
}, {})

console.log(Object.values(grouped))

如果每个对象具有更多的动态时间范围,例如0-1s等,则可以在reduce参数中destrcuture个对象来获取countryrest时间范围内的各个属性。遍历rest的{​​{3}},以更新每个time范围的值:

const input = [{"0-1s":6,"1-2s":2,country:"us"},{"0-1s":1,"1-2s":4,country:"ja"},{"0-1s":3,"1-2s":9,country:"ca"}];

const grouped = input.reduce((r, { country, ...rest }) => {
  Object.entries(rest).forEach(([time, v]) => {
    r[time] = r[time] || { time };
    r[time][country] = v
  })

  return r;
}, {})

console.log(Object.values(grouped))

答案 1 :(得分:1)

以下是使用reduce()的动态代码。首先获取唯一键数组,即['0-1s','1-2s'],然后将其转换为对象。然后在reduce()上使用arr并将属性添加到其中。

const arr = [{
   '0-1s': 6,
   '1-2s': 2,
   country: "us"
}, {
   '0-1s': 1,
  '1-2s': 4,
   country: "ja"
}, {
   '0-1s': 3,
   '1-2s': 9,
   country: "ca"
}]

const obj = [...new Set(arr.map(x => Object.keys(x).filter(a => a.includes('-'))).flat())].reduce((ac,a) => (ac[a]=({time:a}),ac),{});

const res = arr.reduce((ac,a) => {
  Object.keys(a).forEach(x => {
    if(x.includes('-')) ac[x][a.country] = a[x];
  })
  return ac;

},obj)

console.log(Object.values(res))

答案 2 :(得分:0)

您可以通过模块化方式(可重用性的概念)进行尝试。

  

我使用了在数组上定义的 map()方法来创建新数组。

     

注意:您可以定义键来停止不必要的迭代,或者如果您的数组很大且大多数键都已匹配,则没问题。

// function 1
function getNewArray(arr) {
    let newArr = [];

    if(arr.length) {
        let keys = ["0-1s", "1-2s"];

        newArr = keys.map((key) => {
            let newObj = {}
            // console.log(newObj, key)

            for(let obj of arr) {               
                if(newObj["time"] === undefined) {
                    newObj["time"] = key
                }
                newObj[obj["country"]] =obj[key]
            }

            return newObj
        })
    } 

    return newArr
}

// function 2
function test() {
    let arr = [{
           "0-1s": 6,
           "1-2s": 2,
           country: "us"
        }, {
           "0-1s": 1,
           "1-2s": 4,
           country: "ja"
        }, {
           "0-1s": 3,
           "1-2s": 9,
           country: "ca"
        }]

    let newArr = getNewArray(arr)
    console.log(newArr)
    /*
        [ { time: '0-1s', us: 6, ja: 1, ca: 3 },
      { time: '1-2s', us: 2, ja: 4, ca: 9 } ]
    */

    /* --- Pretty printing --- */
    console.log(JSON.stringify(newArr, null, 4))
    /*
        [
            {
                "time": "0-1s",
                "us": 6,
                "ja": 1,
                "ca": 3
            },
            {
                "time": "1-2s",
                "us": 2,
                "ja": 4,
                "ca": 9
            }
        ]
    */
}

// Start
test()