对象数组中 对值相同的数据进行合并 —— 递归函数写法

  在做许多管理系统的时候我们会遇到许多需要对表格数据进行合并的需求,如下图所示:

  

  在上述例子中,我们得到的数据可能是扁平的,类似于

[{
		'品类':'帽子/针织/长巾',
		'配色/尺码':'红褐色/L',
		'生产计划数':'800顶',
		'纱线':'42支哔哩啪啦',
		'颜色':'蓝色',
		'重量':'10千克'
	},{
		'品类':'帽子/针织/长巾',
		'配色/尺码':'红褐色/L',
		'生产计划数':'800顶',
		'纱线':'32支哔哩啪啦',
		'颜色':'蓝色',
		'重量':'10千克'
	},{
		'品类':'帽子/针织/长巾',
		'配色/尺码':'红褐色/L',
		'生产计划数':'800顶',
		'纱线':'42支哔哩啪啦',
		'颜色':'紫色',
		'重量':'10千克'
	},{
		'品类':'帽子/针织/长巾',
		'配色/尺码':'红褐色/L',
		'生产计划数':'800顶',
		'纱线':'42支哔哩啪啦',
		'颜色':'紫色',
		'重量':'10千克'
	}]
...........

  不难发现,这个扁平数组中上面有相当多重复数据,也就是可以合并的数据,我们可能会希望对部分值相同的数据进行合并,比如我们希望先对品类相同的数据合并,再根据尺码/配色相同的数据也进行一次合并,然后..........

  最终我们得到表格所需要展示的合并后的多层结构的对象。

  这里我提供一个可以合并扁平数据的函数,有需要的可以看一下下面的例子,后面注释的一部分代码是一些思考,需要讨论的可以扫左上角二维码

<script type="text/javascript">

let json = [{
	sex:'女',
	name:'女1号',
	from:'中国'
},{
	sex:'女',
	name:'女2号',
	from:'中国'
},{
	sex:'女',
	name:'女3号',
	from:'韩国'
},{
	sex:'男',
	name:'男1号',
	from:'中国'
},{
	sex:'男',
	name:'男2号',
	from:'韩国'
},{
	sex:'男',
	name:'男3号',
	from:'美国'
},{
	sex:'男',
	name:'男4号',
	from:'中国'
}]

function jsonMerge(jsonArr,keyArr){
	let newJson = [] //合并好的数据都放在这个数组里
	jsonArr.forEach((itemJson,indexJson)=>{
		let mark = -1
		let finded = newJson.find((itemFind, indexFind) => {
			if (itemFind[keyArr[0]] === itemJson[keyArr[0]]) {
				mark = indexFind
				return itemFind[keyArr[0]] === itemJson[keyArr[0]]
			}
		})
		if(!finded){
			let value = {}
			value[keyArr[0]] = itemJson[keyArr[0]]
			value['info'] = []
			let info = {}
			for(let i in itemJson){
				if(i!==keyArr[0]){
					info[i] = itemJson[i]
				}
			}
			value['info'].push(info)
			newJson.push(value)
		}else{
			let info = {}
			for(let i in itemJson){
				if(i!==keyArr[0]){
					info[i] = itemJson[i]
				}
			}
			newJson[mark]['info'].push(info)
		}
	})
	// 递归的条件是不断的缩减keyArr的length,每次都去除第零个,直到为0
	if(keyArr.length === 1){
		return newJson
	}else{
		return newJson.map((itemInfo)=>{
			let newKeyArr = []
			keyArr.forEach((item,index)=>{
				if(index>0){
					newKeyArr.push(item)
				}
			})
			return{
				[keyArr[0]]:itemInfo[keyArr[0]],
				'info':jsonMerge(itemInfo['info'],newKeyArr)
			}
		})
	}
}

console.log(jsonMerge(json,['sex','from']))

// function jsonMerge(jsonArr,key,newKey){
// 	let json = jsonArr
// 	let newJson = []
// 	json.forEach((item,index)=>{
// 		let mark = -1
// 		let finded = newJson.find((itemFind,indexFind)=>{
// 			if(itemFind[key]===item[key]){
// 				mark = indexFind
// 				return itemFind[key]===item[key]
// 			}
// 		})
// 		if(!finded){
// 			let value = {}
// 			value[key] = item[key]
// 			value[newKey] = []
// 			let itemJson = {}
// 			for(i in item){
// 				if(i!==key){
// 					itemJson[i] = item[i]
// 				}
// 			}
// 			value[newKey].push(itemJson)
// 			newJson.push(value)
// 		}else{
// 			let itemJson = {}
// 			for(i in item){
// 				if(i!==key){
// 					itemJson[i] = item[i]
// 				}
// 			}
// 			newJson[mark][newKey].push(itemJson)
// 		}
// 	})
// 	return newJson
// }
// let sexMerge = jsonMerge(json,'sex','arr')
// let fromMerge = jsonMerge(json,'from','arr')
// console.log(sexMerge,fromMerge)
/*
	目前能根据单个key进行合并,如我需要合并key值sex,就可以得到
	json = [{
		sex:'女',
		info:[{
			name:'女一号',
			from:'中国'
		},{
			name:'女二号',
			from:'中国'
		} ...]
	},{
		sex:'男',
		info:[{
			name:'男一号',
			from:'中国'
		},{
			name:'男二号',
			from:'韩国'
		} ...]
	}]	

	我想实现的效果,根据多个key进行合并,如我先合并key值sex相同的数据,再合并from相同的数据
	json = [{
		sex:'女',
		info:[{
			from:'中国',
			info:[{
				name:'女1号'
			},{
				name:'女2号'
			}...]
		},{
		sex:'女',
		info:[{
			from:'韩国',
			info:[{
				name:'女3号'
			},{
				name:'女4号'
			}...]
		}]
*/
</script>

最终结果如下

发布了109 篇原创文章 · 获赞 196 · 访问量 30万+

猜你喜欢

转载自blog.csdn.net/dkr380205984/article/details/90699296