This is challenging task for me. I have an array of object. I need to loop thru an array , if there is "message" key, add it to a new array. But there is a tricky thing here. If 'render' is true , I need to get "stageID"(for instance in fisrt element stadeID = 3 ) and move to the third element in that array, get 'message' if there is one , again add it to array and check for "render" status,keep looping until render is false. If in element no 'message' key , but render is true , anyway I need to move to elements by it's stageID.
P/S I always need to get message from first element , doesn't matter if render is true or not
[
{
"algID": 0,
"render": true,
"message": "first message",
"stageID": "3"
},
{
"algID": 0,
"render": false,
"message": "second message",
"message_type": "text"
},
{
"algID": 0,
"render": true,
"message": "third message",
"message_type": "text",
"stageID": "5"
},
{
"algID": 0,
"render": false
},
{
"algID": 0,
"render": false,
"stageID": "4"
},
{
"algID": 0,
"render": false
}
]
Here is my function. I'm adding first element 'message' to array , checking for 'render' but I have no idea how loop it moving thru array using 'stageID'
displayData(step) {
let arrayWithMessage=[]
for (let z = 0; z < step.length; z++) {
if ("message" in step[z]) {
arrayWithMessage.push(step[z].message)
}
if (step[z].render === true) {
console.log("reder true", step[step[z].stageID - 1])
}
}
}
expected output: ['first message', 'third message']
3 Answers 3
You could iterate the array and take either the next element or the stageID - 1 as new index.
var data = [{ algID: 0, render: true, message: "first message", stageID: "3" }, { algID: 0, render: false, message: "second message", message_type: "text" }, { algID: 0, render: true, message: "third message", message_type: "text", stageID: "5" }, { algID: 0, render: false }, { algID: 0, render: false, stageID: "4" }, { algID: 0, render: false }],
result = [],
i = 0;
while (data[i]) {
if (data[i].message) result.push(data[i].message);
if (data[i].render) {
i = data[i].stageID - 1;
continue;
}
i++;
}
console.log(result);
Comments
Let your array is stored in the variable a
var messages = [];
function getMessage(index) {
if (a[index - 1].message !== undefined) {
messages.push(a[index - 1].message);
}
if (a[index - 1].render) {
getMessage(a[index - 1].stageID);
}
}
getMessage(1);
Comments
Edit: is stageID - 1 the index of the next linked post? If yes, this solution or Ninas is corrent.
I interpreted I need to get "stageID"(for instance in fisrt element stadeID = 3 ) and move to the third element in that array as, if stageID = 3, the next element is the 3rd element of the array.
If I understood the logic correctly, something like this could work:
We create a seperate function that will extract all the posts where render is true and a message exists.
Then we can just map that array to extract the posts.
The advantage being that we can easily use it in a mapping function to do that for all the posts.
const posts = [
{ "algID": 0, "render": true, "message": "first message", "stageID": "3" },
{ "algID": 0, "render": false, "message": "second message", "message_type": "text" },
{ "algID": 0, "render": true, "message": "third message", "message_type": "text", "stageID": "5" },
{ "algID": 0, "render": false },
{ "algID": 0, "render": false, "stageID": "4" },
{ "algID": 0, "render": false }
];
const find_message_chain = post => {
const index = parseInt( post.stageID ) - 1;
// If we have render: true, we will need to look for the next post as well.
// By recursively calling find_chain and concatenating all the results, we get a single, one lvel deep array instead of nested arrays we have to .flat() at the end.
if ( post.render && post.message ) return [ post.message, ...find_message_chain( posts[ index ]) ];
// If we do not have render true, but do have a message, this post will br the last one in the chain, so we return it.
else if ( post.message ) return [ post.message ];
// If no message exists, we do not want to return the post, since the chain ends.
else return [];
};
const messages_for_post_0 = find_message_chain( posts[ 0 ] );
console.log( messages_for_post_0 );
const all_messages_per_post = posts.map( find_message_chain );
console.log( all_messages_per_post );
Sidenote 1: I would add an actual ID to the posts, so we do not have to rely on array index of the source data ( posts ) to determine which post is linked to which other post.
Sidenote 2: The recursive chain function can easily be made less exact to allow for arbitary extraction of any value, not only messages.
"second message"?