簡體   English   中英

將JavaScript對象轉換為多維數組的最簡潔方法

[英]Cleanest way to convert JavaScript object to multi-dimensional array

我有一個object arrayrawData )。 array每個object代表各種序列的x坐標和y坐標(即rawData = [(xi,y1i,y2i,..yni)] )。 我想將其轉換為convertedData ,它是objectarray ,其中每個object僅代表一個序列(即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); 

這完全取決於您認為最干凈的東西。 有幾種編程策略,每種策略各有利弊。

這是一種函數編程方法,使用Array原型函數和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; } 

這是一個很好的用例,先在外部數組上進行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)) 

它雖然不漂亮,但卻可以解決問題。 唯一真正令人討厭的部分是Number(item [1] [0]),它將從[“ y2”,“ 1 y2字符串”]中剝離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])
  }
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM