繁体   English   中英

合并两个不同形状的数据结构

[英]merging two data structures of different shapes

我有两个来自两个不同API的形状不同的数据结构。 数据为JSON格式,语言为JavaScript。

阵列1:

[ { "document" : { "html" : "some_html", "name" : "DOCUMENT_NAME_1" },
    "tooltips" : [ { "html" : "some_html", "name" : "TASK_NAME_1" }, 
                   { "html" : "some_html", "name" : "TASK_NAME_2" } ] },
  { "document" : { "html" : "some_html", "name" : "DOCUMENT_NAME_2" },
    "tooltips" : [ { "html" : "some_html", "name" : "TASK_NAME_3" }, 
                   { "html" : "some_html", "name" : "TASK_NAME_4" } ] }]

阵列2:

  [ [ { "name" : "TASK_NAME_1", "status" : "FINISHED" }, 
      { "name" : "TASK_NAME_2", "status" : "OPEN" } ],
    [ { "name" : "TASK_NAME_3", "status" : "OPEN" }, 
      { "name" : "TASK_NAME_4", "status" : "FUTURE" } ] ]

数组1中工具提示字段的元素包含与数组2元素相同的“名称”。如何将数组2中的“状态”优雅地合并到数组1中的工具提示中?

我以为镜头可能是正确的答案,但我不确定,因为我从未使用过它们。

我知道使用嵌套迭代和更新数组1可以解决该问题的一些方法。理想情况下,我正在寻找一种不会修改现有数据结构的方法。

这有点复杂,但它应该对您有用

array2.forEach(function(tooltips){
    tooltips.forEach(function(tooltip){
        for (var i = 0; i < array1.length; i++) {
            for (var j = 0; j < array1[i].tooltips.length; j++) {
                var arr1Tooltip = array1[i].tooltips[j];
                if(arr1Tooltip.name == tooltip.name)
                    arr1Tooltip.status = tooltip.status;
            };
        };        
    });
});

console.log(JSON.stringify(array1));

这可能是工程化的方式,效率不是很高,但是您可以像使用递归函数一样使用此JSFiddle来实现。 我太累了,不能聪明地做到这一点。

var arr1 = [ { "document" : { "html" : "some_html", "name" : "DOCUMENT_NAME_1" },
    "tooltips" : [ { "html" : "some_html", "name" : "TASK_NAME_1" }, 
                   { "html" : "some_html", "name" : "TASK_NAME_2" } ] },
  { "document" : { "html" : "some_html", "name" : "DOCUMENT_NAME_2" },
    "tooltips" : [ { "html" : "some_html", "name" : "TASK_NAME_3" }, 
                   { "html" : "some_html", "name" : "TASK_NAME_4" } ] }];

var arr2 = [ [ { "name" : "TASK_NAME_1", "status" : "FINISHED" }, 
      { "name" : "TASK_NAME_2", "status" : "OPEN" } ],
    [ { "name" : "TASK_NAME_3", "status" : "OPEN" }, 
      { "name" : "TASK_NAME_4", "status" : "FUTURE" } ] ];

var findStatus = function(name, searchArray) {
    var r = '';
    if (typeof searchArray === 'object') {
        if ("name" in searchArray && "status" in searchArray) {
            if (searchArray.name == name) {
                return searchArray.status;
            } else {
                return '';
            }
        } else {
            for (var i in searchArray) {
                r = findStatus(name, searchArray[i]);
                if (r != '') {
                    return r;
                }
            }
        }
    }
    return '';
};

var updateStatus = function(arrToUpdate, arrWithStatus) {
    var copy = $.extend(true, {}, arrToUpdate);
    var r = '';
    if (typeof copy === 'object') {
        if ("name" in copy) {
            r = findStatus(copy.name, arrWithStatus);
            if (r != '') {
                copy.status = r;
            }
        } else {
            for (var i in copy) {
                copy[i] = updateStatus(copy[i], arrWithStatus);
            }
        }
    }
    return copy;
};

var arr3 = updateStatus(arr1, arr2); // Final combined array

我添加了var copy = $.extend(true, {}, arrToUpdate); 行,以便它将进行深层复制而不修改原始数组,因此,它需要jQuery。

由于您的数据结构是嵌套的,因此需要两个zip.map / zipWith

zip(array1, array2).map(function([obj, tooltips]) { // ES6 destructuring syntax
    return {
        document: obj.document,
        tooltips: zip(obj.tooltips, tooltips).map(function([tooltip, extender]) {
            return {
                html: tooltip.html,
                name: tooltip.name,
                status: extender.status
            };
        })
    };
})

如果您不想重复这些对象的文字结构,则可以使用某些复制功能。 例如

extend({}, document, {tooltips:…})
extend({}, tooltip, extender);

您也可以使用类似https://github.com/DrBoolean/lenseshttps://github.com/fantasyland/fantasy-lenses的镜头库,但是我不确定这是否值得-以上代码只需要下划线/破折号。

要绕过内部zipWith ,您需要一个Traversal镜头(我想您对本文很熟悉),但是我还没有看到提供这种功能的JavaScript库。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM