Skip to content

Commit

Permalink
refactor[problems]initialize-method split
Browse files Browse the repository at this point in the history
  • Loading branch information
serfend committed May 27, 2022
1 parent afe24f1 commit d9e1fd3
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 121 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ export default {
updatedb ({ dict, is_manual = true }) {
this.$emit('requireResetProblem', { is_manual, dict })
},
init_status ({ prblems, duplicated }) {
init_status ({ problems, duplicated }) {
const status = {
total: prblems.length,
total: problems.length,
solved: 0,
wrong: 0,
duplicated
Expand Down
127 changes: 8 additions & 119 deletions src/views/problems/Practice/Train/ProblemList/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
<script>
import { beforeLeave, enter, beforeEnter } from './animations'
import { debounce } from '@/utils'
import { shuffle } from '@/utils/data-handle'
import { init_problems } from './problem_init'
export default {
name: 'ProblemList',
components: {
Expand All @@ -55,7 +55,6 @@ export default {
loading: false,
current_focus: null,
filtered_data: null,
total_data_count: 0,
filter_record: {}
}),
computed: {
Expand Down Expand Up @@ -200,12 +199,14 @@ export default {
init (data) {
if (!this.options) return this.$emit('requireInit')
this.loading = true
this.init_problems(data).then(({ prblems, duplicated }) => {
this.$refs.completion_tip.init_status({ prblems, duplicated })
this.$refs.completion_tip.init_wrong_set(prblems)
init_problems(data || this.data, this.options).then(({ problems, duplicated, total_data_count, filter_record }) => {
this.filtered_data = problems
this.filter_record = filter_record
this.$refs.completion_tip.init_status({ problems, duplicated })
this.$refs.completion_tip.init_wrong_set(problems)
setTimeout(() => {
const visual_count = this.filtered_data.length
const hide_count = this.total_data_count - visual_count
const hide_count = total_data_count - visual_count
const { filter_record } = this
if (hide_count > 0) {
this.$notify.warning({
Expand All @@ -220,119 +221,7 @@ export default {
}).finally(() => {
this.loading = false
})
},
filter_with_record ({ items, predict, reason, is_init }) {
if (is_init) {
this.filter_record = {}
return
}
const previous_count = items.length
items = predict(items)
const current_count = items.length
const result = previous_count - current_count
if (result === 0) return items
this.filter_record[reason] = result
return items
},
do_filter_problems (problems) {
const options = this.options
const { problem_range_start, problem_range_end, shuffle_problem, shuffle_problem_options, new_problem, combo_problem, problem_max_num } = options
const dic = this.current_problems
this.filter_with_record({ is_init: true })
let items = problems
items = this.filter_with_record({ items, predict: v => v.filter(i => i), reason: '重复的题目' })
items = this.filter_with_record({ items, predict: v => v.slice(problem_range_start - 1, problem_range_end || v.length), reason: '筛选题目范围' })
if (shuffle_problem) items = shuffle(items)
this.do_shuffle_options(items, shuffle_problem_options)
this.do_attach_analysis(items)
if (combo_problem) items = this.filter_with_record({ items, predict: v => v.filter(i => ((dic[i.id] && dic[i.id].combo_kill) || 0) < combo_problem), reason: '筛选连对' })
if (new_problem) items = this.filter_with_record({ items, predict: v => v.filter(v.filter(i => !(dic[i.id] && dic[i.id].total))), reason: '筛选新题' })
if (problem_max_num > 0) items = this.filter_with_record({ items, predict: v => v.slice(0, problem_max_num), reason: '筛选最大刷题数' })
return items
},
do_attach_analysis (r) {
r.map(i => {
if (!i.options) return
let { analysis } = i
if (!analysis) {
i.analysis = '暂无题解'
return
}
if (i.option_map) {
i.option_map.map((i, index) => {
analysis = analysis.replace(`{{OPT:${i + 1}}}`, `[${index + 1}]`)
})
i.analysis = analysis
}
})
},
do_shuffle_options (r, is_to_shuffle) {
const convert = (map_to, options, answers) => {
const new_options = options.map((i, index) => {
const new_index = map_to[index]
return options[new_index]
})
const map_to_dict = {}
map_to.map((i, index) => {
map_to_dict[i] = index
})
const single_map = i => map_to_dict[i - 1] + 1
const new_answers = answers.length ? answers.map(single_map).sort((a, b) => a - b) : single_map(answers)
return [new_options, new_answers]
}
r.map(i => {
if (!i.options) return
const { options } = i
let { answer, analysis } = i
const check_answer = a => a && (a > 0 && a <= options.length)
if (answer && answer.length) {
// 多选题判断选项合法性
answer = answer.filter(check_answer)
if (!answer.length) {
answer = [1] // 否则设置答案为A
analysis = `(该题答案存在问题)${analysis}`
}
} else if (!check_answer(answer)) {
// 单选题判断选项合法性
answer = 1 // 否则将答案设置为A
analysis = `(该题答案存在问题)${analysis}`
}
let option_map = new Array(options.length).fill(0).map((i, index) => index)
// 如果需要打乱选项
if (is_to_shuffle) {
console.log('start shuffle options')
option_map = shuffle(option_map)
const r = convert(option_map, options, answer, analysis)
i.options = r[0]
i.answer = r[1]
}
i.option_map = option_map
})
},
init_problems (data) {
let prblems = data || this.data || []
return new Promise((res, rej) => {
const id_dict = {}
this.total_data_count = prblems.length
prblems = prblems.map((i) => {
const r = Object.assign({}, i) // 创建新的题目对象
// 若题目没有定义id,则通过题目内容创建id
// TODO 此处应该再按题目内容加入去重筛选
if (!r.id) r.id = `${i.content}${JSON.stringify(i.answer)}`
if (id_dict[r.id]) {
id_dict[r.id]++
return null // 如果id重复,则标记题目为待删除
}
id_dict[r.id] = 1 // 将题目加入重复判断字典中
r.completed = null
return r
})
prblems = this.do_filter_problems(prblems)
prblems = prblems.map((i, page_index) => Object.assign({ page_index }, i)) // 初始化题目的页面位置
this.filtered_data = prblems
return res({ prblems, duplicated: id_dict })
})
},
}
}
}
</script>
Expand Down
137 changes: 137 additions & 0 deletions src/views/problems/Practice/Train/ProblemList/problem_init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@

import { shuffle } from '@/utils/data-handle'
export function filter_with_record ({ items, predict, reason, filter_record }) {
const previous_count = items.length
items = predict(items)
const current_count = items.length
const result = previous_count - current_count
if (result === 0) return items
filter_record[reason] = result
return items
}
import store from '@/store'
/**
* 筛选题目,返回筛选后的题目以及被删的原因
*
* @export
* @param {Array} problems
* @param {Object} options
* @return {Object} items,filter_record
*/
export function do_filter_problems (problems, options) {
let { problem_range_start, problem_range_end, shuffle_problem, shuffle_problem_options, new_problem, combo_problem, problem_max_num } = options
problem_range_start = problem_range_start || 1
problem_range_end = problem_range_end || problems.length
shuffle_problem = shuffle_problem || false
shuffle_problem_options = shuffle_problem_options || false
new_problem = new_problem || false
combo_problem = combo_problem || 0
problem_max_num = problem_max_num || 0

const dic = store.state.problems.current_problems
const filter_record = {}
let items = problems
items = filter_with_record({ items, predict: v => v.filter(i => i), reason: '重复的题目', filter_record })
items = filter_with_record({ items, predict: v => v.slice(problem_range_start - 1, problem_range_end || v.length), reason: '筛选题目范围', filter_record })
if (shuffle_problem) items = shuffle(items)
do_shuffle_options(items, shuffle_problem_options)
do_attach_analysis(items)
if (combo_problem) items = filter_with_record({ items, predict: v => v.filter(i => ((dic[i.id] && dic[i.id].combo_kill) || 0) < combo_problem), reason: '筛选连对', filter_record })
if (new_problem) items = filter_with_record({ items, predict: v => v.filter(v.filter(i => !(dic[i.id] && dic[i.id].total))), reason: '筛选新题', filter_record })
if (problem_max_num > 0) items = filter_with_record({ items, predict: v => v.slice(0, problem_max_num), reason: '筛选最大刷题数', filter_record })
return { items, filter_record }
}
export function do_attach_analysis (r) {
r.map(i => {
if (!i.options) return
let { analysis } = i
if (!analysis) {
i.analysis = '暂无题解'
return
}
if (i.option_map) {
i.option_map.map((i, index) => {
analysis = analysis.replace(`{{OPT:${i + 1}}}`, `[${index + 1}]`)
})
i.analysis = analysis
}
})
}
export function do_shuffle_options (r, is_to_shuffle) {
const convert = (map_to, options, answers) => {
const new_options = options.map((i, index) => {
const new_index = map_to[index]
return options[new_index]
})
const map_to_dict = {}
map_to.map((i, index) => {
map_to_dict[i] = index
})
const single_map = i => map_to_dict[i - 1] + 1
const new_answers = answers.length ? answers.map(single_map).sort((a, b) => a - b) : single_map(answers)
return [new_options, new_answers]
}
r.map(i => {
if (!i.options) return
const { options } = i
let { answer, analysis } = i
const check_answer = a => a && (a > 0 && a <= options.length)
if (answer && answer.length) {
// 多选题判断选项合法性
answer = answer.filter(check_answer)
if (!answer.length) {
answer = [1] // 否则设置答案为A
analysis = `(该题答案存在问题)${analysis}`
}
} else if (!check_answer(answer)) {
// 单选题判断选项合法性
answer = 1 // 否则将答案设置为A
analysis = `(该题答案存在问题)${analysis}`
}
let option_map = new Array(options.length).fill(0).map((i, index) => index)
// 如果需要打乱选项
if (is_to_shuffle) {
console.log('start shuffle options')
option_map = shuffle(option_map)
const r = convert(option_map, options, answer, analysis)
i.options = r[0]
i.answer = r[1]
}
i.option_map = option_map
})
}

/**
* 初始化题目
*
* @export
* @param {*} data 未初始化的题目
* options:偏好设置选项
* @return {*} problems:初始化完成的题目
* duplicated:重复项目
* total_data_count:被筛选前的总数
* filter_record:被筛选掉的题目及原因
*/
export function init_problems (data, options = {}) {
let problems = data
return new Promise((res, rej) => {
const id_dict = {}
problems = problems.map((i) => {
const r = Object.assign({}, i) // 创建新的题目对象
// 若题目没有定义id,则通过题目内容创建id
// TODO 此处应该再按题目内容加入去重筛选
if (!r.id) r.id = `${i.content}${JSON.stringify(i.answer)}`
if (id_dict[r.id]) {
id_dict[r.id]++
return null // 如果id重复,则标记题目为待删除
}
id_dict[r.id] = 1 // 将题目加入重复判断字典中
r.completed = null
return r
})
const { items, filter_record } = do_filter_problems(problems, options)
problems = items.map((i, page_index) => Object.assign({ page_index }, i)) // 初始化题目的页面位置
const total_count = problems.length
return res({ problems, duplicated: id_dict, total_count, filter_record })
})
}
1 change: 1 addition & 0 deletions src/views/problems/Problem/ProblemBase/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export default {
ProblemHeader: () => import('../ProblemBase/ProblemHeader'),
},
props: {
onlyRead: { type: Boolean, default: false },
data: { type: Object, default: null },
focus: { type: Boolean, default: false },
index: { type: Number, default: null }
Expand Down
1 change: 1 addition & 0 deletions src/views/problems/Problem/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export default {
ProblemBase: () => import('./ProblemBase')
},
props: {
onlyRead: { type: Boolean, default: false },
show: { type: Boolean, default: true },
data: { type: Object, default: null },
focus: { type: Boolean, default: false },
Expand Down

0 comments on commit d9e1fd3

Please sign in to comment.