gpt4 book ai didi

javascript - 如何将Javascript对象解析为对象数组

转载 作者:行者123 更新时间:2023-11-28 03:07:17 24 4
gpt4 key购买 nike

我有一个数据对象,需要一个简单的 js 方法将该对象解析为 quill 支持的格式文本编辑器(用链接替换占位符)。

我有:

const data = {
text: 'Hello this is $link1$ and here is $link2$ and now finally $link3$ cool.',
links: {
$link3$: ['link 3', 'https://www.link3.com'],
$link1$: ['link 1', 'https://www.link1.com'],
$link2$: ['link 2', 'https://www.link2.com']
}
};

需要一个简单的 javascript/typescript 函数,我将 data 对象传递给它并返回:

我需要什么:

[
{ insert: 'Hello this is ' },
{
insert: 'link 1',
attributes: { link: 'https://www.link1.com' }
},
{ insert: ' and here is' },
{
insert: 'link 2',
attributes: { link: 'https://www.link2.com' }
},
{ insert: ' and now finally' },
{
insert: 'link 3',
attributes: { link: 'https://www.link3.com' }
},
{ insert: ' cool.' },
]

最佳答案

由于这是 TypeScript,因此定义输入和输出类型的接口(interface)很有帮助。根据您的示例,我将猜测以下内容,但您显然可以更改它们以适合您的用例:

更新:显然 Data 中的 links 属性应该是可选的,因此我将更改它以反射(reflect)这一点。

interface Data {
text: string;
links?: { [k: string]: [string, string] | undefined }
}

interface ParsedData {
insert: string;
attributes?: { link: string }
}

现在我们要定义一个 parse() 函数,它接受 Data 类型的参数并生成 ParsedData[] 类型的结果>。这是一种可能的方法:

const parse = (d: Data): ParsedData[] => d.text.
split(/(\$\w+\$)/).
map(s => ({ s: s, l: d.links?.[s] })).
map(({ s, l }) => l ? { insert: l[0], attributes: { link: l[1] } } : { insert: s });

我在这里所做的是将 text 字符串拆分为由正则表达式 /(\$\w+\$)/ 的匹配项分隔的 block 。该表达式指定一段文本,该文本以美元符号 $ 开头,后跟“单词”字符(字母、数字和下划线),然后以另一个美元符号结束。同样,如果这与您的用例不完全匹配,您可以调整正则表达式来实现这一点。

现在我们有一个要处理的字符串数组。本质上,接下来的两行将每个字符串映射到一个对象。如果字符串是数据的 links 属性的键,它将查找该属性(d.links?.[s] 使用 s 作为 d.links 对象中的属性键;如果 d.links?.[s]undefined,则表示 s 不作为键出现。请注意,?. 表示法是 optional chaining,并考虑了 d.links 本身可能丢失的可能性)并将其格式化为 insert/attributes 对象。否则,它只是将字符串作为 insert 属性,而没有 attributes

这是示例代码的输出:

console.log(JSON.stringify(parse(data)));
/* [
{"insert":"Hello this is "},
{"insert":"link 1","attributes":{"link":"https://www.link1.com"}},
{"insert":" and here is "},
{"insert":"link 2","attributes":{"link":"https://www.link2.com"}},
{"insert":" and now finally "},
{"insert":"link 3","attributes":{"link":"https://www.link3.com"}},
{"insert":" cool."}
] */

这看起来像你想要的。当然,这里存在各种潜在的边缘情况,因此您应该非常小心地明确指定当您收到“奇怪”输入时想要发生的情况。例如,该函数执行以下操作:

console.log(JSON.stringify(parse({
text: "What do you $expect$ to happen here",
links: {
" to happen here": ["oopsie", "doopsie"],
}
})))
/* [
{"insert":"What do you "},
{"insert":"$expect$"},
{"insert":"oopsie","attributes":{"link":"doopsie"}}
] */

这是“正确的”吗?谁知道。所以要小心。

<小时/>

好的,希望有帮助;祝你好运!

Playground link to code

<小时/>

更新:你问如何走另一个方向。这确实是一个单独的问题,但这是我的答案:

function unparse(parsedData: ParsedData[]): Data {

function uniqueLinkKey(links: { [k: string]: any }, displayString: string): string {
const k = displayString.replace(/\W/g, "");
let i: "" | number;
for (i = ""; "$" + k + i + "$" in links; i = +i + 1) { }
return "$" + k + String(i) + "$";
}

const ret: Required<Data> = { text: "", links: {} };
for (let d of parsedData) {
if (d.attributes) {
const key = uniqueLinkKey(ret.links, d.insert);
ret.text += key;
ret.links[key] = [d.insert, d.attributes.link];
} else {
ret.text += d.insert;
}
}
return ret;

}

当输入前一个函数的输出时,会产生以下结果:

console.log(JSON.stringify(unparse(parsedData)));
/* { "text":"Hello this is $link1$ and here is $link2$ and now finally $link3$ cool.",
"links":{
"$link1$":["link 1","https://www.link1.com"],
"$link2$":["link 2","https://www.link2.com"],
"$link3$":["link 3","https://www.link3.com"]
}} */

上面的实现更多的是命令式风格,因为纯功能方法可能过于密集。唯一“有趣”的事情是,如果链接键具有相同的显示文本,您可能永远不想覆盖它们,因此 uniqueLinkKey() 函数确保它生成一个新的正在构建的 links 对象中尚不存在链接键:

console.log(JSON.stringify(unparse([
{ insert: "Repeats are bad: " },
{ insert: "ECHO", attributes: { link: "https://one.example.com" } },
{ insert: " and " },
{ insert: "ECHO", attributes: { link: "https://two.example.com" } },
{ insert: " and " },
{ insert: "ECHO", attributes: { link: "https://three.example.com" } },
{ insert: "!" },
])));
/* {"text":"Repeats are bad: $ECHO$ and $ECHO1$ and $ECHO2$!",
"links":{
"$ECHO$":["ECHO","https://one.example.com"],
"$ECHO1$":["ECHO","https://two.example.com"],
"$ECHO2$":["ECHO","https://three.example.com"]
}} */

所有三个链接都有显示文本 "ECHO",但该函数会生成三个不同的键:"$ECHO$""$ECHO1 $""$ECHO2$"

现在,可能存在各种边缘情况,您应该考虑它们。但我几乎可以肯定已经完成了。祝你好运!

Link to updated code

关于javascript - 如何将Javascript对象解析为对象数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60491367/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com