[英]Insert object into specific position in an array based off property match
I've been at this for a few days and sadly I'm just not able to find the right search terms or the right answers to my lack of skill.我已经在这里工作了几天,遗憾的是我无法找到正确的搜索词或对我缺乏技能的正确答案。
I'm converting ListServ to Discourse.我正在将 ListServ 转换为 Discourse。 I'm converting the RSS feeds to JSON.我正在将 RSS 提要转换为 JSON。 example of the source data:源数据示例:
{
"title": "tech: 18F presentation",
"id": 2,
"body": "Sadly, my biggest concern is whether it will run on Linux or Windows. And I guess if they’ll thrown even more java at it.",
"date": "Fri, 28 May 2021 20:50:04 +0000",
"author": "john_doe"
},
{
"title": "Re: tech: 18F presentation",
"id": 3,
"body": "throw more java, indeed. What a moon shot.",
"date": "Fri, 28 May 2021 20:50:04 +0000",
"author": "john_doe2"
},
{
"title": "Re: tech: 18F presentation",
"id": 4,
"body": "Please stop saying moonshot, its not dodgecoin",
"date": "Fri, 28 May 2021 20:50:04 +0000",
"author": "jane_doe"
},
My data structure needs to look like this:我的数据结构需要如下所示:
{
"topics": [
{
"id": 1,
"title": "tech: 18F presentation",
"pinned": false,
"posts": [
{
"title": "Re: tech: 18F presentation",
"id": 3,
"body": "throw more java, indeed. What a moon shot.",
"date": "Fri, 28 May 2021 20:50:04 +0000",
"author": "john_doe2"
},
{
"title": "Re: tech: 18F presentation",
"id": 4,
"body": "Please stop saying moonshot, its not dodgecoin",
"date": "Fri, 28 May 2021 20:50:04 +0000",
"author": "john_doe2"
},
]
}
]
}
I need each title with "Re: " to be inserted into the original title.我需要将带有“Re:”的每个标题插入到原始标题中。 Example) any reply, "Re tech: 18F presentation" needs to be inserted into posts: [] of the title: "tech: 18F presentation" (no Re: ).示例)任何回复,“Re tech:18F Presentation”需要插入帖子:[] 标题:“tech:18F Presentation”(无 Re:)。
I've tried to sperate the replies into its own json and push that into the post array, but I'm not able to figure out how to match the appropriate title.我试图将回复分散到它自己的 json 并将其推送到帖子数组中,但我无法弄清楚如何匹配适当的标题。
let data = [];
const original_post = [];
const reply_to_post = [];
const discourse_JSON = [];
$("item").map(function (i, article) {
const title = $(article).find("title")[0].children[0].data;
const description = $(article).find("description")[0].children[0].data;
const user_email = $(article).find("author")[0].children[0].data.match("<([^>]+)>")[1];
const link = $(article).find("link")[0].children[0].data;
const guid = $(article).find("guid")[0].children[0].data;
const date = $(article).find("pubDate")[0].children[0].data;
const name = user_email.substring(0,user_email.indexOf('@')).split("_")[0] + ' ' + user_email.substring(0,user_email.indexOf('@')).split("_")[1];
const username = user_email.substring(0,user_email.indexOf('@'))
if (
!title.toLowerCase().includes("vacancy") &&
!title.toLowerCase().includes("opportunity") &&
!title.toLowerCase().includes("retirement") &&
!title.toLowerCase().includes("position") &&
!title.toLowerCase().includes("job posting") &&
!description.toLowerCase().includes("vacancy announcement") &&
!description.toLowerCase().includes("vacancy posting") &&
!description.toLowerCase().includes("vacancies")
) {
data.push({
"title": title,
"id": i,
"body": description,
"date": date,
"author": username
}
});
This is really just a 'groupBy' with a some string manipulation to determine hierarchy.这实际上只是一个“groupBy”,通过一些字符串操作来确定层次结构。
Here is an example using Array#reduce()
and checking if the title startsWith()
'Re:'.这是一个使用Array#reduce()
并检查标题是否为startsWith()
'Re:' 的示例。 If so, remove the initial 'Re:' using String#replace()
and trim()
any white space for consistency.如果是这样,请使用String#replace()
和trim()
删除初始的“Re:”以保持一致性。
const input = [{ "title": "Re: Re: Re: tech: 18F presentation", "id": 3, "body": "throw more java, indeed. What a moon shot.", "date": "Fri, 28 May 2021 20:50:04 +0000", "author": "john_doe2" }, { "title": "tech: 18F presentation", "id": 2, "body": "Sadly, my biggest concern is whether it will run on Linux or Windows. And I guess if they'll thrown even more java at it.", "date": "Fri, 28 May 2021 20:50:04 +0000", "author": "john_doe" }, { "title": "Re: tech: 18F presentation", "id": 4, "body": "Please stop saying moonshot, its not dodgecoin", "date": "Fri, 28 May 2021 20:50:04 +0000", "author": "jane_doe" }, { "title": "Re: other: Title", "id": 6, "body": "throw more java, indeed. What a moon shot.", "date": "Fri, 28 May 2021 20:50:04 +0000", "author": "john_doe2" }, { "title": "other: Title", "id": 5, "body": "Sadly, my biggest concern is whether it will run on Linux or Windows. And I guess if they'll thrown even more java at it.", "date": "Fri, 28 May 2021 20:50:04 +0000", "author": "john_doe" },], byTopic = input.reduce((acc, { title, ...post }) => { if (title.startsWith('Re:')) { const topic = title.replace(/^(?:Re: ){1,}/, '').trim(); acc[topic] || (acc[topic] = { posts: [] }); acc[topic].posts.push({ title: topic, ...post }); // using nullish coalescing assignment // (acc[topic]??= { posts: [] }).posts.push({ title: topic, ...post }); } else { acc[title] = { id: post.id, // your example changes id in the expected output, unsure of the logic title: title, pinned: false, // not sure where pinned is coming from posts: acc[title]? acc[title].posts: [] // using optional chaining and nullish coalescing // posts: acc[title]?.posts?? [] } } return acc; }, {}) console.log(Object.values(byTopic));
.as-console-wrapper { max-height: 100%;important: top; 0; }
As I mentioned in the comments, using reduce()
in this way can be directly replaced with an external accumulator and a for loop.正如我在评论中提到的,以这种方式使用reduce()
可以直接替换为外部累加器和 for 循环。 Here using a for...of
这里使用for...of
const input = [{ "title": "Re: Re: Re: tech: 18F presentation", "id": 3, "body": "throw more java, indeed. What a moon shot.", "date": "Fri, 28 May 2021 20:50:04 +0000", "author": "john_doe2" }, { "title": "tech: 18F presentation", "id": 2, "body": "Sadly, my biggest concern is whether it will run on Linux or Windows. And I guess if they'll thrown even more java at it.", "date": "Fri, 28 May 2021 20:50:04 +0000", "author": "john_doe" }, { "title": "Re: tech: 18F presentation", "id": 4, "body": "Please stop saying moonshot, its not dodgecoin", "date": "Fri, 28 May 2021 20:50:04 +0000", "author": "jane_doe" }, { "title": "Re: other: Title", "id": 6, "body": "throw more java, indeed. What a moon shot.", "date": "Fri, 28 May 2021 20:50:04 +0000", "author": "john_doe2" }, { "title": "other: Title", "id": 5, "body": "Sadly, my biggest concern is whether it will run on Linux or Windows. And I guess if they'll thrown even more java at it.", "date": "Fri, 28 May 2021 20:50:04 +0000", "author": "john_doe" },]; const byTopic = {}; for (const { title, ...post } of input) { if (title.startsWith('Re:')) { const topic = title.replace(/^(?:Re: ){1,}/, '').trim(); byTopic[topic] || (byTopic[topic] = { title: topic, posts: [] }); byTopic[topic].posts.push({ title: topic, ...post }); } else { byTopic[title] = { id: post.id, title: title, pinned: false, posts: [], ...byTopic[title] } } }; console.log(Object.values(byTopic));
.as-console-wrapper { max-height: 100%;important: top; 0; }
Here is a simple solution using the Array.forEach
operator.这是使用Array.forEach
运算符的简单解决方案。 There are probably more efficient solutions, which may be important if you have a large data set:可能有更有效的解决方案,如果您拥有大型数据集,这可能很重要:
const source = [{title:"tech: 18F presentation",id:2,body:"Sadly, my biggest concern is whether it will run on Linux or Windows. And I guess if they’ll thrown even more java at it.",date:"Fri, 28 May 2021 20:50:04 +0000",author:"john_doe"},{title:"Re: tech: 18F presentation",id:3,body:"throw more java, indeed. What a moon shot.",date:"Fri, 28 May 2021 20:50:04 +0000",author:"john_doe2"},{title:"Re: tech: 18F presentation",id:4,body:"Please stop saying moonshot, its not dodgecoin",date:"Fri, 28 May 2021 20:50:04 +0000",author:"jane_doe"}];
let = formatted = [];
// Loop over the original data, find parents
source.forEach((item) => {
// Is not a reply
if (item.title.indexOf('Re:') === -1) {
formatted.push(item);
}
});
// Find children, append to parents
source.forEach((item) => {
formatted.forEach((parent) => {
// Child contains parent title.
if (item.title.indexOf(parent.title) !== -1 && item.title.indexOf('Re:') !== -1) {
if (!parent.data) {
parent.data = [];
}
parent.data.push(item);
}
})
});
console.log(formatted);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.