Tengo la siguiente matriz de objetos; sin embargo, esto podría ser cualquier clave/valor desconocido y anidado infinitamente, por ahora esta es una muestra de prueba:
[ { "reference_id": "R123", "customer": "Person 1", "customer_email": "person1@email.com", "location": "UK", "bookings": [ { "product": "Product 1", "provider": "Company 1", "cancellable": true }, { "product": "Product 2", "provider": "Company 2", "cancellable": true }, { "product": "Product 3", "provider": "Company 1", "cancellable": true } ] }, { "reference_id": "R1234", "customer": "Person 2", "customer_email": "person2@email.com", "location": "USA", "bookings": [ { "product": "Product 1", "provider": "Company 1", "cancellable": true }, { "product": "Product 3", "provider": "Company 1", "cancellable": true } ] }, { "reference_id": "R12345", "customer": "Person 3", "customer_email": "person3@email.com", "location": "UK", "bookings": [ { "product": "Product 2", "provider": "Company 2", "cancellable": true }, { "product": "Product 3", "provider": "Company 1", "cancellable": true } ] } ]Mi implementación actual es la siguiente:
const selected = [ { term: 'Company 1', column: 'provider', }, { term: 'Person 1', column: 'customer', }, ]; const recursivelyFilterByValue = () => (value) => selected.every((item) => { if (!value) return false; if (typeof value === 'string') { // console.log('value', value === item.term); return value === item.term; } if (Array.isArray(value)) { return value.some(this.recursivelyFilterByValue()); } if (typeof value === 'object') { return Object.values(value).some(this.recursivelyFilterByValue()); } return false; }); const results = data.filter(recursivelyFilterByValue());Básicamente, estoy agregando a la matriz "seleccionada" y luego la uso para filtrar la matriz de datos. Quiero asegurarme de que la clave coincida con la "columna", sin embargo, aún no la he agregado.
Para la entrada anterior, esperaría generar lo siguiente:
[ { "reference_id": "R123", "customer": "Person 1", "customer_email": "person1@email.com", "location": "UK", "bookings": [ { "product": "Product 1", "provider": "Company 1", "cancellable": true }, { "product": "Product 2", "provider": "Company 2", "cancellable": true }, { "product": "Product 3", "provider": "Company 1", "cancellable": true } ] }, ]Sin embargo, la matriz de salida está vacía. Si solo busco un término (elimino todos los términos menos uno de la matriz seleccionada), el resultado es correcto para ese término; sin embargo, los términos posteriores devuelven una matriz en blanco.
Me pregunto si mi uso de .some() es el problema, sin embargo, cambiar esto causa demasiados errores de recursión.
Esencialmente, quiero devolver el objeto principal original siempre que haya una coincidencia clave: valor para todas mis condiciones en la matriz seleccionada, en cualquier nivel de sus elementos secundarios.
Cualquier orientación sería muy apreciada, gracias.
Esta solución no es tan bellamente elegante como una respuesta aceptada, pero ¿por qué no mostrar mis esfuerzos? Quizás alguien encuentre esta forma más comprensible.
const selected = [{term: 'Company 1', column: 'provider'}, {term: 'Person 1', column: 'customer'}] const input = [{reference_id: "R123", customer: "Person 1", customer_email: "person1@email.com", location: "UK", bookings: [{product: "Product 1", provider: "Company 1", cancellable: true}, {product: "Product 2", provider: "Company 2", cancellable: true}, {product: "Product 3", provider: "Company 1", cancellable: true}]}, {reference_id: "R1234", customer: "Person 2", customer_email: "person2@email.com", location: "USA", bookings: [{product: "Product 1", provider: "Company 1", cancellable: true}, {product: "Product 3", provider: "Company 1", cancellable: true}]}, {reference_id: "R12345", customer: "Person 3", customer_email: "person3@email.com", location: "UK", bookings: [{product: "Product 2", provider: "Company 2", cancellable: true}, {product: "Product 3", provider: "Company 1", cancellable: true}]}] const iter = (obj, sel) => Object.entries(obj).some(([key, value]) => { if (Array.isArray(value)) return value.some((obj) => iter(obj, sel)); if (typeof value === 'object' && value !== null) return iter(value, sel); return (key === sel.column) && (value === sel.term); }); const deepFilter = (arr, sels) => arr.filter((obj) => sels.every((sel) => iter(obj, sel))); console.dir(deepFilter(input, selected), {depth: null}); .as-console-wrapper {max-height: 100% !important; top: 0}