本文背景
关于开发这个小程序有点历史了,但是由于逻辑相对复杂,每次捡起来都要看代码重新熟悉逻辑,鉴于这个原因,我计划通过该文,把一些逻辑细节通过文字的形式记录下来。
本文内容
本文主要围绕科目维度小程序来讲一个答题小程序的逻辑,所谓科目维度就是该小程序是针对具体某个科目,或者考研或者从业资格考试
按科目维度,就有下一级章节
科目、章节,这是按科目维度的常见划分,但是本文总结的小程序还有一级便是天,把章节里面的考题分成许多天
比如一个科目有10个章节,第一章节下面有100道题,可以把这100道题拆分到10天里面,每天10道题
这样就存在三级目录,这种深层次的目录划分,按照常规用户选择的方式是非常不方便的,本文讨论的小程序,将章节隐藏
科目下面就是天,具体如下图所示
这样,只要选择了科目,具体多少天便可以通过逻辑来控制,相当于只选一次就可以直接到达刷题的题目,交互非常友好。
前期准备
由于这种 科目 — 天 这种特殊的二级目录组织形式,前期要求我们在录入的时候便要拆分好,科目下每一章节具体划分为多少天,为直观展示,我截图下
大家看下面截图的时候,要按照行来看,每一行是一章节,每一章节拆分到哪一天都是固定的,
每一天对应的题库要单独维护,这是前期的一个不小工作量
技术难点
看似我这么叙述好像没有太难的地方,但是加上积分,和支付,答题消耗积分,9元解锁所有答题,所以说,有了这些细节,每个逻辑都相对复杂
逻辑1、
我给关键词叫匹配
我们点击科目,我们要通过该科目所有天和当前已刷题的天,做差集,差集里面的便是我们要本次答题的天
比如,我们拿上图的运动生理学为例,该科目有12章节,共20天,
01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,20
我们当前完成了5天的刷题,分别是01,02,03,04,05
我们选择科目时,就要从上面连个数组求差集,取第一个06
逻辑2、
我给关键词叫解锁
我们点击科目的时候,要判断当前科目是否解锁,所谓的解锁是指,是否已经解锁了科目下的某天,也就是是否已消耗过积分,但是题目还没有刷完
通过上述逻辑1,我们看到下一个刷题的是06,但是06是否已消耗过积分呢,这一点我们便是在逻辑2来完成
如果已消耗过积分,那么直接进入答题
如果未消耗过几分,那么首先核对积分是否充裕,如果积分充裕,再扣掉积分,然后去答题
逻辑3、
我给的关键词叫记忆
所谓记忆就是每次去答题,可能做到中途就提前退出,这个时候,下次进去刷题的时候,是从第一题开始,还是从上次刷题的地方开始
由于这次刷题没有得分的概念,所以把该问题降低了难度,只要记录每次答题的序号就能在下次进入答题的时候,从下一题开始作答
逻辑4、
我给的关键词叫统计分析
在答题的时候有两个维度掌握率、正确率
所谓掌握率就是 已答题数量/总题目数量
所谓正确率是 答题正确数量/已答题数量
还有一个逻辑:当我们在复习错题的时候,是可以移除错题,这个时候相当于正确答题数量+1了
逻辑5、
我给的关键词叫积分
该逻辑看似跟答题无关,但是在答题小程序里面,这个细节是仅此于答题核心逻辑的,
积分系统是一个完善小程序必不可少的,积分获取的规则,积分消耗的规则,这些都是细节中的细节
逻辑6、
我给的关键词叫支付,
该小程序里面涉及9.9解锁所有答题的功能,单次讲支付很简单,但是讲支付融合到业务里面,便复杂一些,支付的优先级高于积分,所以每次判断首先判断是否已支付,
如果没有支付,我们才会走到积分扣减的逻辑里面
备注
通过开发这个小程序,让我从传统答题小程序思维里面跳出来,对我而言,这算是一种全新的模式,需要我不断的理解、消化和吸收。
db.collection('todos').where({ info: _.elemMatch({ name: _.eq('李四') }) }) .get() db.collection('todos').where({ 'info.name': '李四' }) .get()
数组
取并集
let a=new Set([1,2,3,4,5]);
let b=new Set([1,2,3,4,5,6,7,8,9]);
let arr = Array.from(new Set([...a, ...b]));
console.log('arr',arr);
取交集
let a=new Set([1,2,3,4,5]);
let b=new Set([1,2,3,4,5,6,7,8,9]);
let arr = Array.from(new Set([...b].filter(x => a.has(x))));
取差集
let a=new Set([1,2,3,4,5]);
let b=new Set([1,2,3,4,5,6,7,8,9]);
let arr = Array.from(new Set([...b].filter(x => !a.has(x))));
console.log('arr',arr);
数组对象
取交集
let a=[{id:1,a:123,b:1234},{id:2,a:123,b:1234}];
let b=[{id:1,a:123,b:1234},{id:2,a:123,b:1234},{id:3,a:123,b:1234},{id:4,a:123,b:1234}];
let arr = [...b].filter(x => [...a].some(y => y.id === x.id));
console.log('arr',arr)
取差集
let a=[{id:1,a:123,b:1234},{id:2,a:123,b:1234}];
let b=[{id:1,a:123,b:1234},{id:2,a:123,b:1234},{id:3,a:123,b:1234},{id:4,a:123,b:1234}];
let arr = [...b].filter(x => [...a].every(y => y.id !== x.id));
console.log('arr',arr);