Estoy buscando una forma de buscar un nombre dentro de una matriz, incluidas las situaciones en las que la entrada de búsqueda (de varias palabras: nombre, apellido) puede invertirse.
La matriz se vería así con una serie de nombres.
const nombres = ['Alan Hope', 'Greg Day', 'Alan Peters']
La entrada de búsqueda podría ser la siguiente 'Peter Al'
¿Cómo sería el código para lograr esto? Esto es lo que tengo hasta ahora y sé que está totalmente mal.
const studentNames = ['Alan Hope', 'Greg Day', 'Alan Peters'] function search () { const bankingSheet = ss.getSheetByName('Banking') const searchInput = 'Hope Al' const searchWords = searchInput.split(/\s+/) const filtered = studentNames.filter(function(name) { searchWords.every(function(word) { return name.toString().toLowerCase().indexOf(word) !== -1 }) }) Logger.log(filtered) }Por lo que deduzco, primero necesito dividir la entrada de búsqueda en las palabras constituyentes. Luego necesito filtrar a través de la matriz de nombres. Para cada nombre en la matriz, necesito verificar si todas las palabras de búsqueda aparecen de alguna manera en el nombre. Creo que esto puede implicar todos los métodos.
Para cada nombre, si el valor de retorno es verdadero, eso es lo que necesito devolver.
¿Es correcto este pensamiento?
¡Gracias de antemano! ¡Esto realmente me duele la cabeza en este momento!
También puede probar esta implementación de muestra a continuación para encontrar el nombre coincidente incluso cuando la entrada de búsqueda se invierte o el apellido/nombre se abrevia ( por ejemplo, Alan H. o Al Hope ) para un método de búsqueda más flexible:
const studentNames = ['Alan Randolph Hope', 'Greg Herbert Walker Day', 'Alan Jefferson Peters'] function findMatch(){ var match = run("Hope Al"); console.log(match); console.log(match.length>0); } function run(searchString) { var res = []; let findDuplicates = arr => arr.filter((item, index) => arr.indexOf(item) != index); var searches = searchString.split(" "); searches.forEach(search=>{ studentNames.forEach(name =>{ if(name.toLowerCase().includes(search.toLowerCase())){ res.push(name); } }); }); return [...new Set(findDuplicates(res))]; }Hope Al :Greg D :Referencia:
La idea es definir qué se entiende por coincidencia. La coincidencia más simple y rígida es la igualdad de cadenas simple. Una coincidencia más suave toleraría diferencias entre mayúsculas y minúsculas. Aún más suave sería una tolerancia para una inversión de nombre/apellido. (que se muestra en el fragmento).
Lo más suave de todo sería una coincidencia que tolere pequeñas diferencias en los nombres (un reordenamiento no se registraría como una pequeña diferencia a través de una verificación de Levenshtein), a menos que comparemos distancias entre tokens individuales).
const names = ['Alan Hope', 'Greg Day', 'Alan Peters'] function softMatch(nameA, nameB) { if (nameA === nameB) return true; const reverse = name => name.split(' ').reverse().join(' ') const lcA = nameA.toLowerCase(); const lcB = nameB.toLowerCase(); if (lcA === lcB) return true; // case insensitive if (reverse(lcA) === lcB) return true; // order and case insensitive return false } let matches = names.filter(name => softMatch(name, 'peters Alan')) console.log(matches) matches = names.filter(name => softMatch(name, 'No Match')) console.log(matches)Si los nombres van a tener más de dos subnombres, y cualquier orden es una coincidencia, entonces se puede implementar una coincidencia de la siguiente manera...
const names = ['Alan Randolph Hope', 'Greg Herbert Walker Day', 'Alan Jefferson Peters'] function softMatch(nameA, nameB) { let subnamesA = nameA.split(' ').map(n => n.toLowerCase()) let subnamesB = nameB.split(' ').map(n => n.toLowerCase()) // sort lexically and compare subnamesA = subnamesA.sort(); subnamesB = subnamesB.sort(); return subnamesA.every(function(element, index) { return element === subnamesB[index]; }); } let matches = names.filter(name => softMatch(name, 'peters Alan jefferson')) console.log(matches) matches = names.filter(name => softMatch(name, 'No Match')) console.log(matches)