mirror of
https://github.com/geekgeekrun/geekgeekrun.git
synced 2026-09-06 16:07:17 +08:00
178 lines
5.3 KiB
JavaScript
178 lines
5.3 KiB
JavaScript
//# region get all combinations
|
||
// 使用迭代生成组合
|
||
function combine(arr, min, max) {
|
||
const result = []
|
||
const n = arr.length
|
||
|
||
// 生成长度在[min, max]范围内的所有组合
|
||
for (let r = min; r <= Math.min(max, n); r++) {
|
||
const indices = Array(r)
|
||
.fill(0)
|
||
.map((_, i) => i) // 初始化索引
|
||
result.push(indices.map((i) => arr[i])) // 保存初始组合
|
||
|
||
while (true) {
|
||
let i = r - 1
|
||
|
||
// 从后往前找第一个未到达上界的索引
|
||
while (i >= 0 && indices[i] === i + n - r) {
|
||
i--
|
||
}
|
||
|
||
// 没有更多组合时退出
|
||
if (i < 0) break
|
||
|
||
indices[i]++
|
||
|
||
// 更新接下来的所有索引
|
||
for (let j = i + 1; j < r; j++) {
|
||
indices[j] = indices[j - 1] + 1
|
||
}
|
||
|
||
result.push(indices.map((j) => arr[j]))
|
||
}
|
||
}
|
||
|
||
return result
|
||
}
|
||
|
||
// 生成符合"0"限制的组合
|
||
function combineWithZero(arr, min, max) {
|
||
let combineResult;
|
||
if (!Array.isArray(arr)) {
|
||
arr = []
|
||
}
|
||
if (arr.includes(0)) {
|
||
// 如果包含 0,0不参与组合
|
||
combineResult = [].concat(
|
||
combine(
|
||
arr.filter((x) => x !== 0),
|
||
min,
|
||
max
|
||
)
|
||
);
|
||
} else {
|
||
// 如果不包含 0,直接生成组合
|
||
combineResult = [].concat(combine(arr, min, max));
|
||
}
|
||
return combineResult;
|
||
}
|
||
|
||
export function* combineFiltersWithConstraintsGenerator(selectedFilters) {
|
||
const { cityList, salaryList, experienceList, degreeList, scaleList, industryList } =
|
||
selectedFilters;
|
||
|
||
// 生成符合限制条件的组合
|
||
const cityComb = combineWithZero(cityList, 0, 1) // Salary: 0-1 个
|
||
const salaryComb = combineWithZero(salaryList, 0, 1) // Salary: 0-1 个
|
||
const experienceComb = combineWithZero(experienceList, 0, experienceList.length) // Experience: 0 个或更多
|
||
const degreeComb = combineWithZero(degreeList, 0, degreeList.length) // Degree: 0 个或更多
|
||
const scaleComb = combineWithZero(scaleList, 0, scaleList.length) // Scale: 0 个或更多
|
||
const industryComb = combineWithZero(industryList, 0, 3) // Industry: 0-3 个
|
||
|
||
// 通过迭代生成所有组合
|
||
for (const city of cityComb) {
|
||
for (const salary of salaryComb) {
|
||
for (const experience of experienceComb) {
|
||
for (const degree of degreeComb) {
|
||
for (const scale of scaleComb) {
|
||
for (const industry of industryComb) {
|
||
yield {
|
||
cityList: city,
|
||
salaryList: salary,
|
||
experienceList: experience,
|
||
degreeList: degree,
|
||
scaleList: scale,
|
||
industryList: industry
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//#endregion
|
||
|
||
//#region get count of combinations
|
||
|
||
// 计算符合限制条件的组合数量
|
||
export function calculateTotalCombinations(selectedFilters, includeEmptyCondition) {
|
||
const {
|
||
cityList = [],
|
||
salaryList = [],
|
||
experienceList = [],
|
||
degreeList = [],
|
||
scaleList = [],
|
||
industryList = []
|
||
} = selectedFilters
|
||
|
||
// 生成符合限制条件的组合
|
||
const cityComb = combineWithZero(cityList, 0, 1) // City: 0-1 个
|
||
const salaryComb = combineWithZero(salaryList, 0, 1) // Salary: 0-1 个
|
||
const experienceComb = combineWithZero(experienceList, 0, experienceList.length) // Experience: 0 个或更多
|
||
const degreeComb = combineWithZero(degreeList, 0, degreeList.length) // Degree: 0 个或更多
|
||
const scaleComb = combineWithZero(scaleList, 0, scaleList.length) // Scale: 0 个或更多
|
||
const industryComb = combineWithZero(industryList, 0, 3) // Industry: 0-3 个
|
||
|
||
let result = [cityComb, salaryComb, experienceComb, degreeComb, scaleComb, industryComb].reduce((accu, cur) => {
|
||
return accu * cur.length
|
||
}, 1)
|
||
if (!includeEmptyCondition) {
|
||
result -= 1
|
||
}
|
||
return result
|
||
}
|
||
//#endregion
|
||
|
||
export function checkAnyCombineBossRecommendFilterHasCondition(value) {
|
||
if (!Object.keys(value ?? {}).length) {
|
||
return false
|
||
}
|
||
return Object.keys(value).some((k) => {
|
||
return !!value[k]?.length
|
||
})
|
||
}
|
||
|
||
export function getStaticCombineFilterKey(condition) {
|
||
const kAsO = {}
|
||
for (const key of Object.keys(condition ?? []).sort()) {
|
||
if (condition[key] === null || condition[key] === undefined) {
|
||
continue
|
||
}
|
||
kAsO[key] = condition[key]
|
||
}
|
||
return JSON.stringify(kAsO)
|
||
}
|
||
|
||
export function formatStaticCombineFilters(rawStaticCombineRecommendJobFilterConditions) {
|
||
rawStaticCombineRecommendJobFilterConditions = JSON.parse(JSON.stringify(rawStaticCombineRecommendJobFilterConditions))
|
||
const map = new Map()
|
||
for (const condition of rawStaticCombineRecommendJobFilterConditions ?? []) {
|
||
const key = getStaticCombineFilterKey(condition)
|
||
map.set(key, condition)
|
||
}
|
||
const conditions = Array.from(map.values())
|
||
const result = conditions.map((condition) => {
|
||
return {
|
||
cityList: condition.city ? [condition.city] : [],
|
||
salaryList: condition.salary ? [condition.salary] : [],
|
||
experienceList: condition.experience ? [condition.experience] : [],
|
||
degreeList: condition.degree ? [condition.degree] : [],
|
||
scaleList: condition.scale ? [condition.scale] : [],
|
||
industryList: condition.industry ? [condition.industry] : []
|
||
}
|
||
})
|
||
if (!result.length) {
|
||
result.push({
|
||
cityList: [],
|
||
salaryList: [],
|
||
experienceList: [],
|
||
degreeList: [],
|
||
scaleList: [],
|
||
industryList: []
|
||
})
|
||
}
|
||
return result
|
||
}
|