const test1 = [ { name: 'zhanghong', age: 32, money: 0, size: 12, }, { name: 'wanghong', age: 20, size: 6 }, { name: 'jinhong', age: 16, height: 172 }, ] const test2 = [ { name: 'zhanghong', gender: 'male', age: 14 }, { name: 'wanghong', gender: 'female', age: 33 }, { name: 'lihong', gender: 'female', age: 33 }, ] const test3 = [ { name: 'meinv' }, ] const test4 = [ { name: 'aaa' }, ] const test5 = [ { name: 'zhanghong', age: 'wtf' }, ] const result = mergeUnionByKey(test1, test2, test3, test4, [], test5, 'name', 'override') function mergeUnionByKey(...args) { const config = _.chain(args) .filter(_.isString) .value() const key = _.get(config, '[0]') const strategy = _.get(config, '[1]') === 'override' ? _.merge : _.defaultsDeep if (!_.isString(key)) throw new Error('missing key') const datasets = _.chain(args) .reject(_.isEmpty) .filter(_.isArray) .value() const datasetsIndex = _.mapValues(datasets, dataset => _.keyBy(dataset, key)) const uniqKeys = _.chain(datasets) .flatten() .map(key) .uniq() .value() return _.chain(uniqKeys) .map(val => { const data = {} _.each(datasetsIndex, dataset => strategy(data, dataset[val])) return data }) .filter(key) .value() } console.log(JSON.stringify(result, null, 4))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>