如何根据目标对象的键合并两个嵌套的Java脚本对象?

人气:466 发布:2022-10-16 标签: javascript javascript-objects

问题描述

我有两个对象,一个可以被视为超集,另一个可以被视为子集。保证子集具有与超集相似的结构,只是子集将缺少超集的某些属性。

var superset = {
    car: {
        type: 'SUV',
        brand: 'Volvo',
        color: 'Black'
    },
    features: {
        interior: {
            seats: 'leather',
            color: 'black'
        },
        exterior: {
            windows: 'tinted'
        },
        doors: 5
    },
    warranty: '5 yrs'
}

var subset = {
    car: {
        type: true,
        brand: true        
    },
    features: {
        interior: {
            seats: true            
        },
        exterior: {
            windows: true
        },
        doors: true
    }
}

我想合并这两个对象,使用超集的值,但只针对子集中存在的属性。结果应该如下所示:

{
    car: {
        type: 'SUV',
        brand: 'Volvo'
    },
    features: {
        interior: {
            seats: 'leather'
        },
        exterior: {
            windows: 'tinted'
        },
        doors: 5
    }
}

mergeWith来自Lodash的mergeWith几乎完成了这项工作,但它似乎只适用于如下所示的第一级属性。我的想法是,一旦我为所有不需要的属性分配了唯一的值,我就可以遍历并在以后删除它们。

_.mergeWith(subset, superset, function(a, b) {return a ? b : 'DELETE'})

Result:
{
    car: {
        type: 'SUV',
        brand: 'Volvo',
        color: 'Black'
    },
    features: {
        interior: {
            seats: 'leather',
            color: 'black'
        },
        exterior: {
            windows: 'tinted'
        },
        doors: 5
    },
    warranty: 'DELETE'
}

感谢任何帮助。

推荐答案

此解决方案简单地遍历subset(我称之为schema),并从superset(我称之为input)中复制值(如果它们存在)。如果值是两者中的对象,则函数调用自身来处理嵌套属性:

数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">
function merge(input, schema) {
  var result = {}

  for (var k in schema) {
    if (input[k] && typeof input[k] === 'object' && schema[k] && typeof schema[k] === 'object') {
      result[k] = merge(input[k], schema[k])
    } else if (k in input) {
      result[k] = input[k]
    }
  }

  return result
}

var superset = {
  car: {
    type: 'SUV',
    brand: 'Volvo',
    color: 'Black'
  },
  features: {
    interior: {
      seats: 'leather',
      color: 'black'
    },
    exterior: {
      windows: 'tinted'
    },
    doors: 5
  },
  warranty: '5 yrs'
}

var subset = {
  car: {
    type: true,
    brand: true
  },
  features: {
    interior: {
      seats: true
    },
    exterior: {
      windows: true
    },
    doors: true
  }
}

var result = merge(superset, subset)

console.log(result)

361