【javascript】商品种类算法

前言

  • 有小伙伴群里问了个面试题:
  • 有这样一个数据
const a = [
	{ id: "17", caption: "颜色", types: ["黑", "棕"] },
	{ id: "23", caption: "材质", types: ["牛皮"] },
	{ id: "24", caption: "尺码", types: ["40", "41", "42"] },
];
  • 需要让你返回这样的结果:
[
  { '17': '黑', '23': '牛皮', '24': '40' },
  { '17': '黑', '23': '牛皮', '24': '41' },
  { '17': '黑', '23': '牛皮', '24': '42' },
  { '17': '棕', '23': '牛皮', '24': '40' },
  { '17': '棕', '23': '牛皮', '24': '41' },
  { '17': '棕', '23': '牛皮', '24': '42' }
]

思路

  • 这题有点像sku的简版,因为不涉及数量上问题,只要给出所有可能即可。
  • 这题还是有点难的,主要难点就在于需要多层的循环或者嵌套,导致不太好想。
  • 由于types不确定,可以先把types和id做成一个对象,然后迭代对象数组,通过下一个循环迭代出所有可能。
let res = a.reduce((prev,cur)=>{
  let stack = cur.types;
  let arr = []
  while (stack.length!==0){
    let type=stack.shift()
    let obj={}
    obj[cur.id]=type
    arr.push(obj)
  }
  prev.push(arr)
  return prev
},[]).reduce((prev,cur)=>{
  let arr = []
  prev.forEach(a => {
      cur.forEach(b=>{
        arr.push({...a,...b})
      })
  });
  return arr
})
console.log(res)
  • 那么有没有可能一次reduce搞定?那么我们就试着倒推,如果最终结果是那个数组,那么上一次迭代的结果应该是什么?
  • reduce是有prev与cur的,prev用来做累积,最终结果是在prev上,那么没有做最后一次迭代前,生成的数据应该要去除最后那个再去重:
[
  { '17': '黑', '23': '牛皮'},
  { '17': '棕', '23': '牛皮'}
]
  • 第一次的累积结果应该是这样:
[
  { '17': '黑'},
  { '17': '棕'}
]
  • 这里第二个单个,所以看起来第一到第二的过程并不是很明白。
  • 这里直接放答案:
let res = a.reduce((prev, cur) => {
	let stack = cur.types;
	let arr = [];
	while (stack.length !== 0) {
		let type = stack.shift();
		let obj = {};
		obj[cur.id] = type;
		arr.push(obj);
	}
  let sr = [];
  if(prev.length===0){
    sr.push(...arr)
  }else{
    for (let i = 0; i < arr.length; i++) {
      for (let k = 0; k < prev.length; k++) {
        sr.push({ ...prev[k], ...arr[i] });
      }
    }
  }
  prev=[...sr]
	return prev;
}, []);
console.log(res);

总结

  • reduce是个非常好用的函数,特别是在这种不确定要迭代多少次时候,甚至一个reduce就可以解决这种叠加问题。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

业火之理

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值