Вам нужно перебрать массив results
, а затем провести глубокий поиск каждого объекта на предмет соответствия.Для этого вам нужно будет
- получить все пары ключ / значение
- , если значение является объектом, искать глубже
- , если значение является массивом, искать каждый элемент глубже
- в противном случае (значение является строкой или числом)
- , если ключ находится в списке полей для поиска
- , если значение соответствует запросу, возвращает true
- в противном случае возвращает false
Что-то вроде
const deepSearcher = (fields, query) =>
function matcher(object) {
const keys = Object.keys(object);
return keys.some(key => {
const value = object[key];
// handle sub arrays
if (Array.isArray(value)) return value.some(matcher);
// handle sub objects
if (value instanceof Object) return matcher(value);
// handle testable values
if (fields.includes(key)) {
// handle strings
if (typeof value === "string") return value.includes(query);
// handle numbers
return value.toString() === query.toString();
}
return false;
});
};
Эта функция создает сопоставление для использования с методом .filter
.
const customerFilter = deepSearcher(['customerName', 'customerEmail'], 'jane')
const found = results.filter(customerFilter);
или вы можете передать его непосредственно в .filter
const found = results.filter(deepSearcher(['customerName', 'customerEmail'], 'jane'));
Поля, передаваемые в deepSearcher, не обязательно должны принадлежать одному и тому же объекту.Сопоставитель будет проверять что-либо на соответствие (, но он должен указывать на строку / цифры, чтобы этот код работал ).
Рабочие тестовые случаи
const results = [{
general: {
orderID: "5567",
created: 1548765626101,
status: "new"
},
company: {
companyName: "company x",
companyEmail: "info@companyx.com",
companyContact: "John Doe"
},
customer: {
customerName: "Jane Doe",
customerEmail: "janedoe@email.com"
},
products: [{
productID: 4765756,
productName: "Product x",
productDescription: "Description for product x"
},
{
productID: 4767839,
productName: "Product y",
productDescription: "Description for product y"
}
],
payment: {
price: 1000,
method: "cash"
}
}];
const deepSearcher = (fields, query) =>
function matcher(object) {
const keys = Object.keys(object);
return keys.some(key => {
const value = object[key];
// handle sub arrays
if (Array.isArray(value)) return value.some(matcher);
// handle sub objects
if (value instanceof Object) return matcher(value);
// handle testable values
if (fields.includes(key)) {
// handle strings
if (typeof value === "string") return value.includes(query);
// handle numbers
return value.toString() === query.toString();
}
return false;
});
};
const matchingCustomer = results.filter(deepSearcher(["customerName", "customerEmail"], 'jane'));
console.log('results with matching customer:', matchingCustomer.length);
const matchingProduct = results.filter(deepSearcher(["productName"], 'x'));
console.log('results with matching product:', matchingProduct.length);
const matchingPrice = results.filter(deepSearcher(["price"], '1000'));
console.log('results with matching price:', matchingPrice.length);
const nonMatchingPrice = results.filter(deepSearcher(["price"], '500'));
console.log('results with non matching price:', nonMatchingPrice.length);