如何在Ramda.js中按条件构建促销及积分相关复杂字符串?
需求与问题描述
给定以下变量示例:
var availableDeals = 20; var activatedDeals = 5; var maximumGems = 100; var earnedGems = 70;
需要根据不同条件生成三种促销活动与积分推广消息:
- 已激活20个活动中的5个,已赚取100个gems中的70个,消费更多赚取更多gems。
- 还有15个活动待激活,仅需30个更多gems即可解锁活动(当所需gems≤50时使用'仅需')。
- 还有1个活动待激活,仅需1个更多gems即可解锁活动(当剩余活动/gems数量为1时使用该表述)。
本人尝试编写了如下Ramda.js代码,但无法正确处理所有条件:
const getTitle = (activatedDeals, totalDeals, currentGems, maxGems, requiredGems) => { return R.cond([ [R.equals(0), R.always('No deals to activate')], [R.equals(activatedDeals), R.always('All deals activated')], [R.lt(activatedDeals), R.always(`${totalDeals - activatedDeals} deals to activate`)], [R.T, R.always('- deals to activate')], // Error scenario ])( totalDeals, ) +`, ${currentGems} of ${maxGems} gems, ${requiredGems} more gems to unlock a deal`; }
请问如何针对活动与gems的多种条件完成字符串的正确拼接?
解决方案
你可以把活动状态和宝石需求的逻辑拆成独立的处理单元,再组合出最终消息,这样既符合Ramda的函数式风格,也能清晰覆盖所有条件:
1. 生成活动状态描述
先写一个函数处理活动相关的文本:
const getDealStatusText = (activated, total) => { return R.cond([ [R.equals(0), R.always('无活动可激活')], [R.equals(activated), R.always('所有活动已激活')], [R.pipe(R.subtract(R.__, activated), R.equals(1)), R.always('还有1个活动待激活')], [R.T, R.pipe(R.subtract(R.__, activated), num => `还有${num}个活动待激活`)] ])(total); };
2. 生成宝石需求描述
再写一个函数处理宝石相关的文本:
const getGemRequirementText = (current, max, required) => { const earnedText = `已赚取${max}个gems中的${current}个`; const requiredText = R.cond([ [R.equals(current), R.always('已赚满所有gems')], [R.equals(1), R.always('仅需1个更多gems即可解锁活动')], [R.lte(R.__, 50), num => `仅需${num}个更多gems即可解锁活动`], [R.T, num => `还需${num}个更多gems即可解锁活动`] ])(required); return current < max ? `${earnedText},${requiredText}` : earnedText; };
3. 组合完整推广消息
最后把两个函数整合,处理特殊场景:
const getPromoMessage = (activatedDeals, availableDeals, earnedGems, maximumGems, requiredGems) => { const dealText = getDealStatusText(activatedDeals, availableDeals); if (dealText === '所有活动已激活' || dealText === '无活动可激活') { return dealText; } const gemText = getGemRequirementText(earnedGems, maximumGems, requiredGems); // 触发场景1:已激活部分活动,且所需宝石超过50,提示消费赚更多 const shouldPromptSpend = activatedDeals > 0 && activatedDeals < availableDeals && earnedGems < maximumGems && requiredGems > 50; if (shouldPromptSpend) { return `已激活${availableDeals}个活动中的${activatedDeals}个,${gemText.split(',')[0]},消费更多赚取更多gems。`; } return `${dealText},${gemText}`; };
测试不同场景
// 场景1:已激活5/20,赚70/100,需60宝石(>50触发消费提示) console.log(getPromoMessage(5, 20, 70, 100, 60)); // 输出:已激活20个活动中的5个,已赚取100个gems中的70个,消费更多赚取更多gems。 // 场景2:剩余15个活动,需30宝石(≤50用"仅需") console.log(getPromoMessage(5, 20, 70, 100, 30)); // 输出:还有15个活动待激活,已赚取100个gems中的70个,仅需30个更多gems即可解锁活动 // 场景3:剩余1个活动,需1个宝石 console.log(getPromoMessage(19, 20, 99, 100, 1)); // 输出:还有1个活动待激活,已赚取100个gems中的99个,仅需1个更多gems即可解锁活动
这种拆分方式让每个函数只负责单一逻辑,后续要调整规则也更容易修改。
内容的提问来源于stack exchange,提问作者Aravind Shankar
相关产品推荐
相关产品推荐

