Tengo esto:
{ 'Payment' : { 'Referenced' : 'referenced payment', 'Conciliate' : 'conciliate payment', 'Multiple' : 'multiple payment' } }pero puede cambiar en todo momento por nodos aleatorios o agregar más, como:
{ 'Payment' : { 'Referenced' : 'referenced payment', 'Conciliate' : 'conciliate payment', 'Multiple' : { 'mult1' : 'example1', 'mult2' : 'example1' }, 'Inventory' : { 'datastorage' : 'dt1' } }Todos los nodos se pueden asignar aleatoriamente, y necesito buscar por valor, puedo pasar:
referenced paymenty necesidad:
Payment/Referencedo envío:
example1Y yo necesito:
Payment/Multiple/mult1No sé si existe algo así.
// Function const findPath = (obj, query) => { const makeArray = (obj, path = []) => { const pairs = Object.entries(obj); return pairs.map(([key, value]) => typeof value === "object" ? makeArray(value, [...path, key]) : { path: [...path, key], value } ); }; return ( makeArray(obj) .flat(Infinity) .find(({ path, value }) => value === query)?.path.join("/") ?? null ); }; // Usage const path1 = findPath( { Payment: { Referenced: "referenced payment", Conciliate: "conciliate payment", Multiple: { mult1: "example1", mult2: { test: 123, }, }, Inventory: { datastorage: "dt1", }, }, }, 123 ); const path2 = findPath( { Payment: { Referenced: "referenced payment", Conciliate: "conciliate payment", Multiple: { mult1: "example1", }, Inventory: { datastorage: "dt1", }, }, }, "referenced payment" ); console.log("123: " + path1); console.log("referenced payment: " + path2);Explicación
El primer paso es convertir el objeto en una matriz lineal del árbol de objetos y sus rutas. Esto se hace recursivamente. Luego, la matriz se aplana para iterar con Array.prototype.find , si el valor coincide con la consulta, se devuelve la ruta, si no se encuentra ninguna coincidencia, devuelve null .
Créditos
Gracias a @Bravo por sugerir una matriz de ruta en lugar de una plantilla literal