I have sets of data called series, containing [x,y] pairs, in the format:
[
[x1,a1],
[x2,a2],
[x3,a3],
...
],[
[x4,b1],
[x1,b2],
[x5,b3],
...
]
These multiple sets need to be combined (matching x-values) to fit into Dygraph's data format where all the x-values are the first element of each array:
{
[x1,a1,b2],
[x2,a2,null],
[x3,a3,null],
[x4,null,b1],
[x5,null,b3]
...
}
Ive been trying to use ES6 functions to make this easier but since I am new to javascript I am having trouble finding a good (and fast, as it will handle a lot of data) way to do this. I think I am having more trouble because I don't know the terminology for what I am trying to do which makes googling harder as I am sure this problem is out there somewhere.
Should I be just using a bunch of for loops to make this work or is there a better, efficient way to do this?
Thank you. (I am using mathjs if it has function that could help; i've tried matrix's reshape,concat,etc and none seem to do what I want).
Not sure if the following will work, if your series come from JSON.parse and the keys (x1,x2,x3...) are non primitives then it certainly won't because in ES ({}==={})===false
. So in the example {complexKey:"x1"}
does not equal {complexKey:"x1"}
.
If your keys are strings or numbers (primitive types) the the keys can be compared, if the keys are object types but reference the same object (as in the example data called org
) then it will work as well.
Let me know if you need any help with some more details about what your series is, what errors you are getting, what code you are using what you expect and what actually happens (please no "doesn't work").
const complexX1Key = {complexKey:"x1"};//object key x1
const org = [
[
[complexX1Key/* reference to x1 */,{complexValue:"a1"}],
[{complexKey:"x2"},{complexValue:"a2"}],
[{complexKey:"x3"},{complexValue:"a3"}]
],[
[{complexKey:"x4"},{complexValue:"b1"}],
[complexX1Key/* reference to x1 */,{complexValue:"b2"}],
[{complexKey:"x5"},{complexValue:"b3"}]
]
];
const toDygraph = org => {
const flatten = twoDArray =>
twoDArray.reduce(
(all,item)=>
all.concat(item),
[]
);
//get all keys (org[i][0])
const allKeys = flatten(org)
.map(([key])=>key)
.filter((x,index,all)=>all.indexOf(x)===index);//remove double keys
const result =
org//for each [[key:value],[key:value]]
.reduce(
(arr,keyValues)=>{//keyValues is [[key,value],[key,value]]
allKeys.forEach(//for every key in all keys
key=>{
//find an item [key,value] in current value set that has key
// of current key in all keys
const val = keyValues.find(([x])=>x===key);
//find in arr (arr is [[key],[key],[key]])
arr.find(([x])=>x===key)
//add the found value ([key,value]) to this [key] or add null if not found
.push((val&&val[1])||null);
}
)
return arr;
},
allKeys.reduce(//create an array of [[key1],[key2],[key3]]
(all,key)=>
all.concat([[key]]),
[]
)
);
return result;
}
console.log(
JSON.stringify(toDygraph(org),undefined,2)
);