[英]How to conditionally filter an array of objects that includes duplicates in Javascripts
I have an array of objects like following, some commands share the same text:我有一个对象数组,如下所示,一些命令共享相同的文本:
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",
},
]
I want to filter this array out based on the user input message.我想根据用户输入消息过滤掉这个数组。 Also, for the commands that have the same text, I only want the first one (or the default one).
此外,对于具有相同文本的命令,我只想要第一个(或默认的)。 For example, if the user input ["read a book"], the result would be
例如,如果用户输入 ["read a book"],结果将是
[
{
id: "id2",
text: "read",
message: "read a book",
},
{
id: "id3",
text: "sleep",
message: "sleep",
},
{
id: "id4",
text: "help",
message: "help",
},
]
if the user input ["read a message"], which does not exist in the array, the default one will be returned, the result would be如果用户输入 ["read a message"],它在数组中不存在,则返回默认值,结果为
[
{
id: "id1",
text: "read",
message: "read",
},
{
id: "id3",
text: "sleep",
message: "sleep",
},
{
id: "id4",
text: "help",
message: "help",
},
]
Here is my JavaScripts/TypeScripts,这是我的 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
)
I wonder if there is better way to solve this?我想知道是否有更好的方法来解决这个问题?
You could group by text
and take the object for a matching message.您可以按
text
分组,然后将 object 用于匹配消息。
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; }
A chainable approach with reduce
一种带有
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; }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.