I need to combine the array results in js based on the header names. The number of arrays passed for processing is not known and it can vary from 2 to 30 plus arrays and the final expected result is a combination of column data based on header names.
The input array column orders may be shuffled as shown below
array1 = [
["A","B","C"], // headers
["AA1","BB1","CC1"],
["AAA1","BBB1","CCC1"], ...
]
array2 = [
["B","C","A", "D"], //headers
["BB2","CC2","AA2", "DD2"],
["BBB2","CCC2","AAA2","DDD2"],...
]
...
arrayn = [
["A","C","B", ...], //headers
["AAn","CCn","BBn", ...],
["AAAn","CCC2","BBBn", ...],...
]
result =
[
["A","B","C", "D"],
["AA1","BB1","CC1",""],
["AAA1","BBB1","CCC1",""],
["AA2","BB2","CC2","DD2"],
["AAA2","BBB2","CCC2,"DDD2"],
...
["AAn","BBn","CCn",...],
["AAAn","BBBn","CCCn,...],
]
I have tried with
for(var i=0;i<array1;i )
{
for(var j=0;j<array2;j )
{
if(array1[i][j]==array2[0][j])
{
result.push(array[i][j])
}
}
}
UDPATE: The number of columns may vary from input array, but they all would appear in the result. Like array2 has D column and the result would have DD2 and DDD2
CodePudding user response:
You have to loop through the arrays seperately. Keep a reference header, In each array mark the first element as the header and rest as data using spread operator. Loop through the rest of data by tracking the indices in the header for each array.
Working Code
const array1 = [
["A", "B", "C"], // headers
["AA1", "BB1", "CC1"],
["AAA1", "BBB1", "CCC1"],
]
const array2 = [
["B", "C", "A"], //headers
["BB2", "CC2", "AA2"],
["BBB2", "CCC2", "AAA2"],
]
const arrayn = [
["A", "C", "B"], //headers
["AAn", "CCn", "BBn"],
["AAAn", "CCC2", "BBBn"],
]
const result = [];
const header = ["A", "B", "C"];
result.push(header);
function addArray(arr) {
const [itemHeader, ...rest] = arr;
const [orderA, orderB, orderC] = [itemHeader.indexOf(header[0]), itemHeader.indexOf(header[1]), itemHeader.indexOf(header[2])];
rest.forEach((item) => {
const orderedArray = [item[orderA], item[orderB], item[orderC]];
result.push(orderedArray);
})
}
addArray(array1);
addArray(array2);
addArray(arrayn);
console.log(result);
EDIT
Generic Method
Logic
- Use a function
generateResult
which accepys dynamic number of parameters. - Segregare the headers from that list. For that loop through the params. Take the first node of each param which is the header.
flatMap
it to generate the complete list of headers as a single array. Create a new set with this list to get the unique values, Sort it to define an order. - Loop through the params, split each params into two using spread operator. The first item is the header of that node which is called as
nodeHeader
and rest is the data. - The order of the output is obtained by comparing this node header and the main header list.
- Loop through the data array and return the values in the specified order.
Working Fiddle
const array1 = [
["A", "B", "C"], // headers
["AA1", "BB1", "CC1"],
["AAA1", "BBB1", "CCC1"],
]
const array2 = [
["B", "C", "A", "D"], //headers
["BB2", "CC2", "AA2", "DD2"],
["BBB2", "CCC2", "AAA2", "DDD2"],
]
const array3 = [
["B", "C", "D"], //headers
["BB3", "CC3", "DD3"],
["BBB3", "CCC3", "DDD3"],
]
const arrayn = [
["A", "C", "B"], //headers
["AAn", "CCn", "BBn"],
["AAAn", "CCC2", "BBBn"],
]
const result = [];
function getNode(item, header) {
const [ nodeHeader, ...data ] = item;
const orderList = header.map(node => nodeHeader.indexOf(node));
const retVal = data.map(node => orderList.map(order => order === -1 ? "" : node[order]));
return retVal;
}
function generateResult(...list) {
// Generate unique array of headers using set.
const header = Array.from(new Set(list.flatMap(item => item[0]))).sort(); // Selecting header
const rest = list.flatMap((item, index) => getNode(item, header));
const result = [header, ...rest];
console.log(result);
}
generateResult(array1, array2, array3, arrayn);
CodePudding user response:
What you do is just create a map with witch you can migrate old column to the new one. To to do so you have just to take the first array as reference and create a function that do the migration.
var array1 = [
["A","B","C"], // headers
["AA1","BB1","CC1"],
["AAA1","BBB1","CCC1"]];
var array2 = [
["B","C","A"], //headers
["BB2","CC2","AA2"],
["BBB2","CCC2","AAA2"]
];
// get the headers for result
// we take the first array as base then we add the other arary to it
var result = [];
result = array1;
var resultheader = result[0];
var resultheaderIndexMap = {};
//we create a map which indicate which letters belong te which column
for(var i = 0; i < resultheader.length; i ){
var tmpval = resultheader[i];
resultheaderIndexMap[tmpval] = i;
}
function AppendArray(result, newArray, resultheaderIndexMap){
// We create a map from the header in order to migrate the old index
// to the new one in order
var indexFromOldToNewMap = {};
var tpmHeeader = array2[0];
for(var i = 0; i< tpmHeeader.length; i ){
var tmpval = tpmHeeader[i];
var newIndex = resultheaderIndexMap[tmpval];
var oldIndex = i;
indexFromOldToNewMap[oldIndex] = newIndex;
}
//then we use it to migrate
for(var i = 1; i < array2.length; i ){
var tab = array2[i];
var resultTab = [];
for(var y = 0; y < tab.length; y ){
var newIndex = indexFromOldToNewMap[y];
var tmpval = tab[y];
resultTab[newIndex] = tmpval;
}
result.push(resultTab);
}
return result;
}
AppendArray(result, array2, resultheaderIndexMap);