关于JavaScript中reduce的使用场景

16 篇文章 0 订阅

reduce常见的可能就是

// array.reduce(function(total, currentValue, currentIndex, arr), ?initialValue)

[1, 2, 3, 4].reduce((pre, next) => pre + next, 0)

值得注意的是initialValue如果没传值 , 默认是array的第一个值,currentIndex是从1开始的,而不是0开始。

reduce的另外一种场景就是递归。
例如下面的算法题。

定义52张扑克牌(无大小王), 扑克牌需定义花色与数字。 (花色简称: 红桃-H, 梅花-C, 方块-D,黑桃-S)
顺子固定长度为5张牌,不用考虑K之后到A的情况
定义一个函数,让用户选择两张扑克牌, 函数返回所有可能的顺子组合, 如果能形成同花顺,在开始前打印(SF).
如: 调用 searchStraight(D2, D5) ->
打印结果: SF->DA, D2, D3, D4, D5
HA, D2, H3, D4, D5

共包含 xxxx 顺子

参考题解:

// test.ts
const HS = ['S', 'H', 'C', 'D'];
const Lab = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'];
class PK {
	hs: string;
	label: string;
	value: number;
	constructor(hs: string, value: number) {
		if (value < 0 || value > Lab.length - 1 || HS.indexOf(hs) < 0) {
			throw new Error('请输入正确的牌!');
		}
		this.hs = hs;
		this.value = value;
		this.label = Lab[value];
	}
}

const searchStraight = (input1: string, input2: string) => {
	if (Object.prototype.toString.call(input1) !== '[object String]' ||
		Object.prototype.toString.call(input2) !== '[object String]'
	) {
		throw new Error('请输入正确的牌!');
	}
	const pk1 = new PK(input1.substring(0, 1), Lab.indexOf(input1.substring(1)))
	const pk2 = new PK(input2.substring(0, 1), Lab.indexOf(input2.substring(1)))
	const smaller = pk1.value > pk2.value ? pk2 : pk1;
	const bigger = pk1.value > pk2.value ? pk1 : pk2;

	const result: PK[][] = [];
	const min = bigger.value - 4 < 0 ? 0 : bigger.value - 4;
	const max = smaller.value;
	for (let value = min; value <= max; value++) {
		result.push(...createArr5(value, smaller, bigger))
	}

	result.forEach(sz => {
		if (pk1.hs == pk2.hs && sz.filter(pk => pk.hs === pk1.hs).length === 5) {
			console.log(`SF-->${sz.map(pk => pk.hs + pk.label).join(',')}`)
		} else {
			console.log(sz.map(pk => pk.hs + pk.label).join(','))
		}
	})
	console.log(`共包含 ${result.length} 顺子`)
}

const createArr5 = (value: number, smaller: PK, bigger: PK) => {
	const indexArr = new Array(5).fill('')

	return indexArr.reduce<PK[][]>((previousValue, _, currentIndex) => {
		const result: PK[][] = [];
		if (currentIndex === 0) {
			if (smaller.value === value) {
				result.push([new PK(smaller.hs, value)]);
			} else {
				for (let i = 0; i < HS.length; i++) {
					const hs = HS[i];
					result.push([new PK(hs, value)]);
				}
			}
		} else {
			for (let j = 0; j < previousValue.length; j++) {
				const element = [...previousValue[j]];
				const currentValue = value + currentIndex
				if (currentValue === smaller.value) {
					result.push([...element, new PK(smaller.hs, currentValue)]);
				} else if (currentValue === bigger.value) {
					result.push([...element, new PK(bigger.hs, currentValue)]);
				} else {
					for (let i = 0; i < HS.length; i++) {
						const hs = HS[i];
						result.push([...element, new PK(hs, currentValue)]);
					}
				}
			}
		}

		return result;
	}, [])
}

searchStraight('S8', 'SJ')

上面主要的算法就在createArr5 ,利用reduce去递归,比起正常递归调用,思路更加清晰, 每一步结果一个自动传下去;
思路就是:
顺子就是一个排列组合问题,如图
更具输入的input1input2计算出边界;然后计算每一种顺子不同花色的排列组合;顺子的长度相当于for循环的层数 ,也就是递归的次数;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值