代码之家  ›  专栏  ›  技术社区  ›  Sandeep Gupta

将JavaScript对象转换为多维数组的最简单方法

  •  1
  • Sandeep Gupta  · 技术社区  · 6 年前

    我有一个 array 属于 object ( rawData ). 每个 对象 这个的 阵列 表示各种系列的x坐标和y坐标(即, rawData = [(xi,y1i,y2i,..yni)] )中。我想把它转换成 convertedData ,这是一个 阵列 对象 其中每个 对象 只表示一个序列(即, convertedData = [[(xi,y1i)], [(xi,y2i)]...[(xi,yni)]] )

    rawData = [{
        x: 1,
        y1:"1 y1 string", 
        y2:"1 y2 string",
        y3:"1 y3 string",
    
        yn:"1 yn string",
    },{
        x: 2,
        y1:"2 y1 string", 
        y2:"2 y2 string",
        y3:"2 y3 string",
    
        yn:"2 yn string",
    }];
    
      convertedData = [
        {
          name:"y1",
          data:[
            [1,"1 y1 string"],
            [2,"2 y1 string"],
          ]
        },{
          name:"y2",
          data:[
            [1,"1 y2 string"],
            [2,"2 y2 string"],
          ]
        },{
          name:"y3",
          data:[
            [1,"1 y3 string"],
            [2,"2 y3 string"],
          ]
        },{
          name:"yn",
          data:[
            [1,"1 yn string"],
            [2,"2 yn string"],
          ]
        }
      ];
    

    什么是javascript方法来干净地尝试这个?


    我做的工作:

    let convertedData = [];
    rawData = [{
        x: 1,
        y1:"1 y1 string",
        y2:"1 y2 string",
        y3:"1 y3 string",
    
        yn:"1 yn string",
    },{
        x: 2,
        y1:"2 y1 string",
        y2:"2 y2 string",
        y3:"2 y3 string",
    
        yn:"2 yn string",
    }];
    
    function findDataByName(convertedData, name){
        for (let i=0; i<convertedData.length;++i){
            if(convertedData[i].name === name)
                return convertedData[i].data;
        }
        return temp;
    }
    
    function convert() {
        /*initialize the convertedData*/
        Object.keys(rawData[0]).forEach((value)=>{
            if(value==='x') return;
            convertedData.push({
                name:value,//y1
                data:[]//[(xi,y1i)]
            })
        });
    
        /*now loop over rawData and fill convertedData's data array*/
        rawData.forEach((obj)=>{
            Object.keys(obj).forEach((key)=>{
                if(key==='x') return;
                let data = findDataByName(convertedData,key);
                data.push([obj['x'], obj[key]]);//pushing a new coordinate
            });
        })
    }
    
    convert();
    console.log(convertedData);
    3 回复  |  直到 6 年前
        1
  •  1
  •   Mark    6 年前

    这是一个很好的 reduce 在外部数组上,然后在每个对象的项上循环。

    let rawData = [{x: 1,y1:"1 y1 string", y2:"1 y2 string",y3:"1 y3 string",yn:"1 yn string",},{x: 2,y1:"2 y1 string", y2:"2 y2 string",y3:"2 y3 string",yn:"2 yn string",}];
    
    let obj = rawData.reduce((o, item) => {
        Object.entries(item).forEach(([key, val]) => {
            if (key === 'x') return
            if (o.hasOwnProperty(key)){
                let data = o[key].data
                data.push([data.length+1, val])
            } else {
                o[key] = {name: key, data: [[1, val]]}
            }
        })
        return o
    }, {})
    
    // obj is an object, but you are only interested in the values:
    console.log(Object.values(obj))
        2
  •  1
  •   trincot Jakube    6 年前

    这取决于你认为什么是最干净的有几种编程策略,每种都有其优缺点。

    这是一个 函数式程序设计 方法,使用数组原型函数和ES6 Map 作为临时哈希将数据分组 x 价值。

    const rawData = [{x: 1,y1:"1 y1 string",y2:"1 y2 string",y3:"1 y3 string",yn:"1 yn string",},{x: 2,y1:"2 y1 string",y2:"2 y2 string",y3:"2 y3 string", yn:"2 yn string", }];
    
    const convertedData = Array.from(rawData.reduce( 
        (map, obj) => Object.keys(obj).filter(key => key != "x").reduce(
            (map, key) => map.set(key, (map.get(key) || []).concat([[obj.x, obj[key]]])),
            map
        ),
        new Map
    ), ([name, data]) => ({name, data}));
    
    console.log(convertedData);
    .as-console-wrapper { max-height: 100% !important; top: 0; }
        3
  •  0
  •   Aidan Hoolachan    6 年前

    它不漂亮,但它确实起到了作用唯一真正令人讨厌的部分是数字(项[1][0]),它将从[“y2”,“1y2 string”]中去掉1

    //Flatten the data
    const y = rawData.map(item => {
      return Object.entries(item).filter(entry => entry[0] !== 'x');
    }).reduce((acc, curr) => acc.concat(curr), []);
    
    //Create yheader array: ["y1", "y2"..., "yn"];
    const yHeaders = [... new Set(y.map(item => item[0]))];
    
    //for each y header, build the corresponding data object 
    const clean = yHeaders.map(targetHeader => {
      return {
        name: targetHeader,
        data: y.filter(item => item[0] === targetHeader).map(item => [ Number(item[1][0]), item])
      }
    });