【问题标题】:Joining array columns based on headers基于标题连接数组列
【发布时间】:2022-01-20 04:36:53
【问题描述】:

我需要根据标题名称将数组结果组合到js中。传递给处理的数组数量是未知的,它可以从 2 到 30 多个数组不等,最终的预期结果是基于标题名称的列数据的组合。

输入数组的列顺序可能会被打乱,如下图所示

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,...],
]

我试过了

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:列数可能与输入数组不同,但它们都会出现在结果中。像 array2 有 D 列,结果将有 DD2 和 DDD2

【问题讨论】:

    标签: javascript arrays


    【解决方案1】:

    您必须分别循环遍历数组。保留一个引用标头,在每个数组中将第一个元素标记为标头,并使用扩展运算符将其余元素标记为数据。通过跟踪每个数组标头中的索引来循环其余数据。

    工作代码

    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);

    编辑

    通用方法

    逻辑

    • 使用函数generateResult 接受动态数量的参数。
    • 从该列表中分离标题。通过参数循环。取每个参数的第一个节点,即标头。 flatMap 它将完整的标题列表生成为单个数组。使用此列表创建一个新集合以获取唯一值,对其进行排序以定义顺序。
    • 遍历参数,使用扩展运算符将每个参数分成两个。第一项是该节点的标头,称为nodeHeader,其余是数据。
    • 通过比较这个节点头和主头列表得到输出的顺序。
    • 循环遍历数据数组并按指定顺序返回值。

    工作小提琴

    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);

    【讨论】:

    • 谢谢 Nitheesh,我用 UPDATE 更改了问题,这可以适应吗?
    • @CodeGuy 请检查更新的答案以获得通用解决方案。
    【解决方案2】:

    您所做的只是创建一个带有女巫的地图,您可以将旧列迁移到新列。为此,您只需将第一个数组作为参考并创建一个执行迁移的函数。

    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);
    

    【讨论】:

      猜你喜欢
      • 2018-03-07
      • 2018-11-19
      • 2019-02-04
      • 2023-03-09
      • 2017-03-17
      • 2017-12-15
      • 1970-01-01
      • 2020-06-06
      • 2011-10-05
      相关资源
      最近更新 更多