Tengo una serie de objetos como los siguientes, algunos comandos comparten el mismo texto:
const Commands=[ { id: "id1", text: "read", message: "read", }, { id: "id2", text: "read", message: "read a book", }, { id: "id3", text: "sleep", message: "sleep", }, { id: "id4", text: "help", message: "help", }, { id: "id5", text: "help", message: "command help", }, ]Quiero filtrar esta matriz según el mensaje de entrada del usuario. Además, para los comandos que tienen el mismo texto, solo quiero el primero (o el predeterminado). Por ejemplo, si el usuario ingresa ["leer un libro"], el resultado sería
[ { id: "id2", text: "read", message: "read a book", }, { id: "id3", text: "sleep", message: "sleep", }, { id: "id4", text: "help", message: "help", }, ]si el usuario ingresa ["leer un mensaje"], que no existe en la matriz, se devolverá el predeterminado, el resultado sería
[ { id: "id1", text: "read", message: "read", }, { id: "id3", text: "sleep", message: "sleep", }, { id: "id4", text: "help", message: "help", }, ]Aquí están mis JavaScripts/TypeScripts,
const defaultReadText = Commands.find( (command) => command.message === userReadMessage )?.text ?? "read" const defaultReadMessage = Commands.find( (command) => command.message === userReadMessage )?.message ?? "read" const defaultHelpText = Commands.find( (command) => command.message === userHelpMessage )?.text ?? "help" const defaultHelpMessage = Commands.find( (command) => command.message === userHelpMessage )?.message ?? "help" const enabledCommands = Commands.filter( (command) => (command.text === defaultReadText && command.message === defaultReadMessage) || command.text != defaultReadText )?.filter( (command) => (command.text === defaultHelpText && command.message === defaultHelpMessage) || command.text != defaultHelpText )Me pregunto si hay una mejor manera de resolver esto.
Puede agrupar por text y tomar el objeto para un mensaje coincidente.
const filter = (array, message) => Object.values(array.reduce((r, o) => { if (!r[o.text] || o.message === message) r[o.text] = o; return r; }, {})), commands = [{ id: "id1", text: "read", message: "read" }, { id: "id2", text: "read", message: "read a book" }, { id: "id3", text: "sleep", message: "sleep" }, { id: "id4", text: "help", message: "help" }, { id: "id5", text: "help", message: "command help" }]; console.log(filter(commands)); console.log(filter(commands, "read a book")); console.log(filter(commands, "read a message")); .as-console-wrapper { max-height: 100% !important; top: 0; } Un enfoque encadenable con reduce
const filter = message => (r, o) => { if (r[r.length - 1]?.text === o.text) { if (o.message === message) r[r.length - 1] = o; } else { r.push(o); } return r; }, commands = [{ id: "id1", text: "read", message: "read" }, { id: "id2", text: "read", message: "read a book" }, { id: "id3", text: "sleep", message: "sleep" }, { id: "id4", text: "help", message: "help" }, { id: "id5", text: "help", message: "command help" }]; console.log(commands.reduce(filter(), [])); console.log(commands.reduce(filter("read a book"), [])); console.log(commands.reduce(filter("read a message"), [])); .as-console-wrapper { max-height: 100% !important; top: 0; }