Skip to content

Instantly share code, notes, and snippets.

@AlexanderKomkov
Last active August 17, 2023 14:15
Show Gist options
  • Save AlexanderKomkov/f2b2783657fbf6a15e0804cf83299d3c to your computer and use it in GitHub Desktop.
Save AlexanderKomkov/f2b2783657fbf6a15e0804cf83299d3c to your computer and use it in GitHub Desktop.
В функцию поиска модифкации приходят 3 параметра:
1) Selector - объект параметра по которому проищошло изменение
Поля: paramId - ID параметра, multiple - флаг множественный, value - новое значение (строка или массив строк), prevValue - предыдущее значение (строка или массив строк)
Шаг 1. Фильтруем модификации
1) Если параметр множественный:
Нужно определить состояние параметра (было добавлено новое значение, было убавлено значение, параметр стал пустым)
В зависимости от состояния разный алгоритм фильтрации
2) Параметр одиночный
Ищем модификации, где есть такой параметр
Шаг 2. Из отфильтрованных модификации ищем наиболее похожую
Поиск наиболее похожей модификации, определяем в какой модифкации будет меньше менять параметров
Если у модификаций одинаковое кол-во изменений, то показываем первую
export interface Selector {
paramId: string
multiple: boolean
value: string | string[]
prevValue: string | string[]
}
import {Selector} from "@/models/Selector";
export default class VehicleServices {
static VehicleModificationSearch(
Selector: Selector,
Modifications: Array<any>,
ActiveModificationValue: Array<any>
): any {
// Шаг 1. Фильтруем модификации
let filterModifications: any[] = []
if (Selector.multiple) {
if (Selector.value.length) {
if (Selector.value.length > Selector.prevValue.length) {
// Добавилось значение множественного параметра
// Ищем разницу (что именно добавилось)
let difference: string[] = Selector.value.filter(
(paramValue: string): boolean => !Selector.prevValue.includes(paramValue)
)
if (difference.length) {
Modifications?.forEach((modification: any): void => {
modification.params?.forEach((param: any): void => {
if (param.param_id === Selector.paramId) {
if (param.value === difference[0]) {
filterModifications.push(modification)
}
}
})
})
}
} else {
// Убавилось значение множественного параметра
// Находим перекрестье
let intersection: any[] = Selector.value.filter(
(paramValue: string): boolean => Selector.prevValue.includes(paramValue)
)
// Ищем разницу (что именно убавилось)
let difference: any[] = Selector.prevValue.filter(
(paramValue: string) => !Selector.value.includes(paramValue)
)
if (intersection.length && difference.length) {
Modifications?.forEach((modification: any): void => {
let issetRemoteValue: boolean = false
let issetSearchValue: boolean = false
modification.params?.forEach((param: any): void => {
if (param.param_id === Selector.paramId) {
if (intersection.includes(param.value)) {
issetSearchValue = true
}
if (param.value === difference[0]) {
issetRemoteValue = true
}
}
})
// Если найдены совпадения по другим значениям и не найдено убавленное значение
if (issetSearchValue && !issetRemoteValue) {
filterModifications.push(modification)
}
})
}
}
} else {
// Пустое значение множественного параметра
// Ищем модификации, где нет значений такого параметра
Modifications?.forEach((modification: any): void => {
let emptyParamValue: boolean = true
modification.params?.forEach((param: any): void => {
if (param.param_id === Selector.paramId) {
emptyParamValue = false
}
})
if (emptyParamValue) {
filterModifications.push(modification)
}
})
}
} else {
// Одиночный параметр
Modifications?.forEach((modification: any): void => {
modification.params?.forEach((param: any): void => {
if (param.param_id === Selector.paramId) {
if (param.value === Selector.value) {
filterModifications.push(modification)
}
}
})
})
}
// Шаг 2. Из отфильтрованных модификации ищем наиболее похожую
let costs: any[] = []
let maxCost: number = -10000
filterModifications?.forEach((modification: any, index: number): void => {
console.log('Расчет стоимости совпадений для модификации:')
console.log(modification)
let cost: number = 0
modification.params?.forEach((param: any) => {
if (param.param_id === Selector.paramId) {
console.log('Искомый параметр')
console.log('Значение: ' + Selector.value + ', ID параметра ' + param.param_id)
if (Selector.multiple) {
if (Selector.value.includes(param.value)) {
cost += 100
console.log('Совпадение по параметру, значение ' + param.value + ', ID параметра ' + param.param_id)
console.log('+100')
} else {
cost -= 30
console.log('Не найдено значение ' + param.value + ', ID параметра ' + param.param_id)
console.log('-30')
}
} else {
if (param.value === Selector.value) {
cost += 500
console.log('Совпадение по параметру, значение ' + param.value + ', ID параметра ' + param.param_id)
console.log('+500')
} else {
cost -= 30
console.log('Не найдено значение ' + param.value + ', ID параметра ' + param.param_id)
console.log('-30')
}
}
} else {
const ValueParam: string | string[] = ActiveModificationValue[param.param_id]
console.log('Параметр')
console.log('Значение ' + ValueParam + ', ID параметра ' + param.param_id)
if (typeof ValueParam == 'object') {
if (ValueParam.includes(param.value)) {
cost += 30
console.log('Совпадение по параметру, значение ' + param.value + ', ID параметра ' + param.param_id)
console.log('+30')
} else {
cost -= 5
console.log('Не найдено значение ' + param.value + ', ID параметра ' + param.param_id)
console.log('-5')
}
} else {
if (param.value === ValueParam) {
cost += 50
console.log('+50')
console.log('Совпадение по параметру, значение ' + param.value + ', ID параметра ' + param.param_id)
} else {
cost -= 5
console.log('Не найдено значение ' + param.value + ', ID параметра ' + param.param_id)
console.log('-5')
}
}
}
})
console.log('Стоимость: ' + cost)
console.log('-----')
costs.push({ cost: cost, index: index })
if (cost > maxCost) {
maxCost = cost
}
})
const resultIndex: any = costs.filter((item: any): boolean => {
return item.cost == maxCost
})
const index = resultIndex[0] ? resultIndex[0]?.index : 0
return filterModifications[index]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment