У меня есть веб-сайт, который взаимодействует со сторонним API, который будет обрабатывать расходы на доставку продуктов. На нашем веб-сайте «productId» соответствует их «externalProductId» в их каталоге, но у них есть несколько записей для нашего ProductID, поскольку они классифицируют разные ProductId в своей базе данных на основе ProductId и веса. поэтому на нашем веб-сайте один продукт, такой как «Сумка», имеет несколько записей, поскольку у них есть несколько записей для продуктов «Сумки» в зависимости от введенного веса. Веб-сайт также является международным, поэтому вес указан как в фунтах, так и в килограммах. Нам нужно сопоставить наш ProductId с их «externalProductId» и выбрать правильный продукт из их каталога, чтобы мы могли отправить его в их API ценообразования. Мне нужно было бы выполнить этот поиск для каждого продукта, который клиент выбирает на нашем веб-сайте, чтобы отправить его в API ценообразования грузоотправителя, чтобы они могли увидеть оценку доставки.
Еще одна проблема заключается в том, что их минимальный вес для всех продуктов всегда равен 0, поэтому я мог бы также добавить логику в поиск по массиву, где я жестко закодирую, как найти продукт, который находится между их максимальным весом> 50 фунтов, но <70 фунтов, но завтра, если они изменят цену. / диапазонов веса для них это не сработает, поэтому я предпочел бы динамически находить продукты в их каталоге с правильным весом, которые соответствуют нашим ProductId и «externalProductId», и находить правильный вариант из нескольких совпадений, находящихся в диапазоне веса. Может ли кто-нибудь указать, какой способ поиска в каталоге будет наиболее эффективным на основе этих нескольких критериев поиска?
Вот образец товара с нашего сайта
{ 'productId' : 'BAG', 'weight': 60, 'unit':'lbs' }
В их каталоге есть два продукта, соответствующие «externalProductId»: «BAG», но правильный соответствующий продукт, который мне нужно будет найти в их каталоге продуктов, будет потому, что он также соответствует диапазону веса.
{
"productId": "BG2",
"externalProductId": "BAG",
"productName": "Bag",
"weight": {
"minimum": [
{
"minWeight": 0,
"unit": "lbs"
},
{
"minWeight": 0,
"unit": "kgs"
}
],
"maximum": [
{
"maxWeight": 70,
"unit": "lbs"
},
{
"maxWeight": 32,
"unit": "kgs"
}
]
}
},
Каталог продукции сторонних производителей со всеми продуктами.
[
{
"productId": "BG1",
"externalProductId": "BAG",
"productName": "Bag",
"weight": {
"minimum": [
{
"minWeight": 0,
"unit": "lbs"
},
{
"minWeight": 0,
"unit": "kgs"
}
],
"maximum": [
{
"maxWeight": 50,
"unit": "lbs"
},
{
"maxWeight": 23,
"unit": "kgs"
}
]
}
},
{
"productId": "BG2",
"externalProductId": "BAG",
"productName": "Bag",
"weight": {
"minimum": [
{
"minWeight": 0,
"unit": "lbs"
},
{
"minWeight": 0,
"unit": "kgs"
}
],
"maximum": [
{
"maxWeight": 70,
"unit": "lbs"
},
{
"maxWeight": 32,
"unit": "kgs"
}
]
}
},
{
"productId": "GF1",
"externalProductId": "GLF",
"productName": "Golf Bag",
"weight": {
"minimum": [
{
"minWeight": 0,
"unit": "lbs"
},
{
"minWeight": 0,
"unit": "kgs"
}
],
"maximum": [
{
"maxWeight": 50,
"unit": "lbs"
},
{
"maxWeight": 23,
"unit": "kgs"
}
]
}
},
{
"productId": "GF2",
"externalProductId": "GLF",
"productName": "Golf Bag",
"weight": {
"minimum": [
{
"minWeight": 0,
"unit": "lbs"
},
{
"minWeight": 0,
"unit": "kgs"
}
],
"maximum": [
{
"maxWeight": 70,
"unit": "lbs"
},
{
"maxWeight": 32,
"unit": "kgs"
}
]
}
},
{
"productId": "MI1",
"externalProductId": "MUS",
"productName": "Music Instrument",
"weight": {
"minimum": [
{
"minWeight": 0,
"unit": "lbs"
},
{
"minWeight": 0,
"unit": "kgs"
}
],
"maximum": [
{
"maxWeight": 50,
"unit": "lbs"
},
{
"maxWeight": 23,
"unit": "kgs"
}
]
}
},
{
"productId": "MI2",
"externalProductId": "MUS",
"productName": "Music Instrument",
"weight": {
"minimum": [
{
"minWeight": 0,
"unit": "lbs"
},
{
"minWeight": 0,
"unit": "kgs"
}
],
"maximum": [
{
"maxWeight": 70,
"unit": "lbs"
},
{
"maxWeight": 32,
"unit": "kgs"
}
]
}
}
]
@Cbroe будет два совпадающих продукта на основе нашего идентификатора продукта: «BAG» и их внешнего идентификатора продукта: «BAG», но тогда мне нужно будет сузить его до правильного результата, основанного также на весе.
Для каждого соответствующего внешнего идентификатора вычтите фактический вес из максимального веса и возьмите наименьшую разницу >= 0.
вам вообще нужно переосмыслить свою логику, поскольку они используют externalProductId как категорию, а не как уникальный идентификатор.
индексация по externalProductId, и результат того, что каждый индекс представляет собой двоичное дерево, должен помочь, тогда будет найдено наименьшее число, большее, чем ваше значение в parsedObj[someId], или просто индексация через externalProductId, и каждый элемент будет представлять собой их массив и логика, которую упомянул @James
Если вам нужно вернуть совпадающие продукты на основе нескольких условий, вы можете легко сделать это с помощью нескольких различных методов массива. В этом примере reduce
кажется наиболее подходящим для многоусловного использования.
Пожалуйста, посмотрите сценарий ниже:
const findMatchingProducts = (externalProductId, maxProductWeight, productWeightUnit) => {
const matchingWeightProducts = data.reduce((acc, curr) => {
// filter out any products without a matching externalProductId
if (curr.externalProductId !== externalProductId) {
return acc;
}
const {
weight: {
minimum,
maximum,
},
} = curr;
const { minWeight } = minimum.find(min => min.unit === productWeightUnit) || {};
const { maxWeight } = maximum.find(max => max.unit === productWeightUnit) || {};
// filter out any products that don't fall within the min/max weight range
const isAboveMinWeight = minWeight <= maxProductWeight;
const isBelowMaxWeight = maxWeight >= maxProductWeight;
// if the product falls within the min/max weight range, add it to the list of matched products
if (isAboveMinWeight && isBelowMaxWeight) {
acc.push(curr);
}
return acc;
}, []);
// return the list of matched products
return matchingWeightProducts;
};
console.info(findMatchingProducts('BAG', 60, 'lbs'));
Результат:
[
{
"productId": "BG2",
"externalProductId": "BAG",
"productName": "Bag",
"weight": {
"minimum": [
{
"minWeight": 0,
"unit": "lbs"
},
{
"minWeight": 0,
"unit": "kgs"
}
],
"maximum": [
{
"maxWeight": 70,
"unit": "lbs"
},
{
"maxWeight": 32,
"unit": "kgs"
}
]
}
}
]
В этом примере data
— это массив продуктов, возвращаемых из стороннего каталога. В функции findMatchingProducts
она делает следующее:
externalProductId
Если вам всегда нужно возвращать только один продукт, вам может потребоваться добавить дополнительные свойства для дальнейшей фильтрации набора результатов или вы можете просто выбрать первый результат как «наилучшее соответствие». Если вам нужно выполнить точное совпадение минимального и максимального весов, вы можете изменить условие, которое будет использоваться ===
при сравнении весов, а не просто проверять, что они ниже или выше пороговых значений.
спасибо @nick-w-nick, это потрясающе! Я подумывал объединить несколько операторов в цепочку для проверки этих условий, но вы показали, как объединить всю логику в одной функции сокращения. Мне нужно больше использовать сокращение для подобных вещей, ценю вашу помощь!
Если в вашем стороннем массиве может быть только один подходящий продукт, то вы, вероятно, захотите сделать это, используя Developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…