Javascript - 将子对象合并到公共父对象中

时间:2017-09-06 13:45:01

标签: javascript arrays object merge lodash

我有一个父对象数组,在这样的结构中有嵌套的子数组:

[
  {
    "fullName": "Certificate",
    "checked": false,
    "children": [
      {
        "type": "Certificate",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Certificate-1",
      }
    ]
  },
  {
    "fullName": "InstalledPackage",
    "checked": false,
    "children": [
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Package1",
      }
    ]
  },
  {
    "fullName": "InstalledPackage",
    "checked": false,
    "children": [
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Package2",
      }
    ]
  },
  {
    "fullName": "Network",
    "checked": false,
    "children": [
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Network1",
      }
    ]
  }
]

我想在将孩子们推到一起的同时将任何父节点与相同的'fullName'合并。所需的输出是:

[
  {
    "fullName": "Certificate",
    "checked": false,
    "children": [
      {
        "type": "Certificate",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Certificate-1",
      }
    ]
  },
  {
    "fullName": "InstalledPackage",
    "checked": false,
    "children": [
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Package1",
      },
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Package2",
      }
    ]
  },
  {
    "fullName": "Network",
    "checked": false,
    "children": [
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Network1",
      }
    ]
  }
]

有没有一种优雅的方法来达到这个目标(使用lodash或其他方式)?我已根据找到的答案here尝试了许多循环解决方案,但我无法做到这一点。有什么想法吗?

@Andy,我尝试的大部分代码都基于超链接中的答案,一个看起来很有希望的尝试是:

function mergeNames (arr) {
    return _.chain(arr).groupBy('fullName').mapValues(function (v) {
        return _.chain(v).map('fullName').flattenDeep();
    }).value();
}

console.log(mergeNames(array));

但这个输出是“lodash包装”?并且不能正确地将孩子们推到一起 - 我想也许是因为我在孩子和父级都有相同的标识符(fullName)?当我运行此代码并从chrom控制台复制输出时,我得到以下内容:

{
  "Certificate": [
    "Certificate"
  ],
  "InstalledPackage": [
    "InstalledPackage",
    "InstalledPackage"
  ],
  "Network": [
    "Network"
  ]
}

3 个答案:

答案 0 :(得分:1)

您可以使用Array.prototype这样的方法执行此操作:

let data = [
  {
    "fullName": "Certificate",
    "checked": false,
    "children": [
      {
        "type": "Certificate",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Certificate-1",
      }
    ]
  },
  {
    "fullName": "InstalledPackage",
    "checked": false,
    "children": [
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Package1",
      }
    ]
  },
  {
    "fullName": "InstalledPackage",
    "checked": false,
    "children": [
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Package2",
      }
    ]
  },
  {
    "fullName": "Network",
    "checked": false,
    "children": [
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Network1",
      }
    ]
  }
];

let result = data.reduce((res, elem) => {
	let arrForChecking = res.filter((el) => el.fullName === elem.fullName);

	if (arrForChecking.length) {
		arrForChecking[0].children.push(elem.children[0]);

		return res;
	}

	return res = res.concat(elem);
}, []);

console.log(result);

答案 1 :(得分:0)

您可以定义组合分组的键,并在将单个组推送到结果数组时使用组的哈希表。

var array = [{ fullName: "Certificate", checked: false, children: [{ type: "Certificate", lastModifiedDate: "1971-01-01T00:00:00.000Z", fullName: "Certificate-1" }] }, { fullName: "InstalledPackage", checked: false, children: [{ type: "InstalledPackage", lastModifiedDate: "1971-01-01T00:00:00.000Z", fullName: "Package1" }] }, { fullName: "InstalledPackage", checked: false, children: [{ type: "InstalledPackage", lastModifiedDate: "1971-01-01T00:00:00.000Z", fullName: "Package2" }] }, { fullName: "Network", checked: false, children: [{ type: "InstalledPackage", lastModifiedDate: "1971-01-01T00:00:00.000Z", fullName: "Network1" }] }],
    hash = Object.create(null),
    keys = ['fullName', 'checked'],
    grouped = [];

array.forEach(function (o) {
    var key = keys.map(function (k) { return o[k]; }).join('|');
    if (!hash[key]) {
        hash[key] = {};
        keys.forEach(function (k) { hash[key][k] = o[k]; });
        hash[key].children = [];
        grouped.push(hash[key]);
    }
    hash[key].children = hash[key].children.concat(o.children);
});

console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

ES6

var array = [{ fullName: "Certificate", checked: false, children: [{ type: "Certificate", lastModifiedDate: "1971-01-01T00:00:00.000Z", fullName: "Certificate-1" }] }, { fullName: "InstalledPackage", checked: false, children: [{ type: "InstalledPackage", lastModifiedDate: "1971-01-01T00:00:00.000Z", fullName: "Package1" }] }, { fullName: "InstalledPackage", checked: false, children: [{ type: "InstalledPackage", lastModifiedDate: "1971-01-01T00:00:00.000Z", fullName: "Package2" }] }, { fullName: "Network", checked: false, children: [{ type: "InstalledPackage", lastModifiedDate: "1971-01-01T00:00:00.000Z", fullName: "Network1" }] }],
    hash = Object.create(null),
    keys = ['fullName', 'checked'],
    grouped = [];

array.forEach(function (o) {
    var key = keys.map(k => o[k]).join('|');
    if (!hash[key]) {
        hash[key] = Object.assign({}, o);
        grouped.push(hash[key]);
        return;
    }
    hash[key].children.push(...o.children);
});

console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 2 :(得分:0)

你去吧

as = [
  {
    "fullName": "Certificate",
    "checked": false,
    "children": [
      {
        "type": "Certificate",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Certificate-1",
      }
    ]
  },
  {
    "fullName": "InstalledPackage",
    "checked": false,
    "children": [
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Package1",
      }
    ]
  },
  {
    "fullName": "InstalledPackage",
    "checked": false,
    "children": [
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Package2",
      }
    ]
  },
  {
    "fullName": "Network",
    "checked": false,
    "children": [
      {
        "type": "InstalledPackage",
        "lastModifiedDate": "1971-01-01T00:00:00.000Z",
        "fullName": "Network1",
      }
    ]
  }
]

ad = []
i=-1
as.forEach(function(item, index){
  if(index>0){
    i=i+1
    if(as[index]['fullName'] === as[i]['fullName']) {
      item['children'] = item['children'].concat(as[i]['children'])
      ad[ad.length - 1] = item
    } else {
      ad.push(item)
    }
  } else {
    ad.push(item)
  }
})