1

I have an array of objects like this :

var finalresult = [{
    "Date": "Wed Jan 15 2020 00:00:00 GMT+0530 (India Standard Time)",
    "data": [{
            "intent": "delivery",
            "result": [{
                "heading": "Delivered",
            }]
        },
        {
            "intent": "orders",
            "result": [{
                "heading": "What is the order status"
            }]
        },
        {
            "intent": "orders",
            "result": [{
                "heading":"Where is my order"
            }]
        }
    ]
},{
    "Date": "Wed Jan 17 2020 00:00:00 GMT+0530 (India Standard Time)",
    "data": [{
            "intent": "feedback",
            "result": [{
                "heading": "Hello",
            }]
        },
        {
            "intent": "feedback",
            "result": [{
                "heading": "You are good"
            }]
        },
        {
            "intent": "picnic",
            "result": [{
                "heading":"Lets go on picnic"
            }]
        } ,
        {
            "intent": "picnic",
            "result": [{
                "heading":"Are you coming for the picnic?"
            }]
        } ,
        {
            "intent": "order",
            "result": [{
                "heading":"When should I pick my order"
            }]
        }
    ]
}]

This is the final output that I expect :

[{
    "Date": "Wed Jan 15 2020 00:00:00 GMT+0530 (India Standard Time)",
    "keywords" : "delivery,orders",
    "html" : "<h1>Delivered</h1><h1>What is the order status</h1><h1>Where is my order</h1>"
},{
    "Date": "Wed Jan 17 2020 00:00:00 GMT+0530 (India Standard Time)",
    "keywords" : "feedback,picnic,order",
    "html" : "<h1>Hello</h1><h1>You are good</h1><h1>Lets go on picnic</h1><h1>Are you coming for the picnic?</h1><h1>When should I pick my order</h1>"
}]

This is what I tried so far:

    var chatstring = "";
    var final = [];
    keywordset = new Set();
    // console.log(JSON.stringify(finalresult))
    for (i = 0; i < finalresult.length; i++) {
        ////chatarr +="<div class='collapsible'></div>";
        for (j = 0; j < finalresult[i].data.length; j++) {
            //console.log(finalresult[c].data)
            keywordset.add(finalresult[i].data[j].intent);
            // console.log(summary);
            generatehtml(finalresult[j].data)
            nloop++;
            if (nloop == (finalresult.length)) {

               final.push(chatstring)
            }
        }

        //forEach
    }

    function generatehtml(data) {
    return new Promise((resolve, reject) => {
        for (s = 0; s < data.length; s++) {

            for (t = 0; t < data[s].result.length; t++) {
                var response = data[s].result[t].heading;
                  var html = "<div" + response + "</div>";
                  chatstring += html;
            }

        }

    })
}

I'm using a set to store unique values of intent. I'm using the generatehtml() function to loop over the data and generate the html.

Expected output :

{"chat": [{
    "Date": "Wed Jan 15 2020 00:00:00 GMT+0530 (India Standard Time)",
    "keywords" : "delivery,orders",
    "html" : "<h1>Delivered</h1><h1>What is the order status</h1><h1>Where is my order</h1>"
},{
    "Date": "Wed Jan 17 2020 00:00:00 GMT+0530 (India Standard Time)",
    "keywords" : "feedback,picnic,order",
    "html" : "<h1>Hello</h1><h1>You are good</h1><h1>Lets go on picnic</h1><h1>Are you coming for the picnic?</h1><h1>When should I pick my order</h1>"
}]}

I'm not able to figure out how to generate the expected output array from the generated data. How do I do it?

0

3 Answers 3

1

There are a lot of ways to do it, as also demonstrated by other users.

Just another one, using .map() to iterate over your first array, and then a .reduce() to build the object with the keywords and the html which is then destructed into your initial.

I have also included comments on each step to be easier for you.

finalresult.map(result => ({ // this will be our final object
  Date: result.Date,
  ...result.data.reduce((accumulator, current) => { // looping through our data
    if (!accumulator.keywords.includes(current.intent)) { // if intent not already in our keywords
       if (accumulator.keywords.length) accumulator.keywords += ','; // if keywords has at least one, add `,`
       accumulator.keywords += current.intent; // add our new keyword
    }

    /** on the next line we map result in case 
     *  array has more than 1 object. We build the 
     *  string we need and while map will return 
     *  an array we use join (with empty string as separator) 
     *  to create a string from our array
     **/
    accumulator.html += current.result.map(res => `<h1>${res.heading}</h1>`).join(''); 

    return accumulator;
  }, { // our initial object, that will be filled be reduce and the destructed into our upper object
    keywords: "",
    html: ""
  }
)
}))

EDIT: After looking OP's comments, as it might occur to get a different key rather than heading, a function/parser building the right output would be cleaner.

The next will also cover multiple keys under the same object.

function myhtmlparser (res) {
  const html = [];

  Object.keys(res).forEach(key => {
    switch (key) {
      case 'heading':
        html.push(`<h1>${res[key]}</h1>`);
        break;
      case 'paragraph':
        html.push(`<p>${res[key]}</p>`);
        break;
    }
  })

  return html.join('');
}

And then use it on your accumulator.html += ...:

accumulator.html += current.result.map(res => myhtmlparser(res)).join(''); 
Sign up to request clarification or add additional context in comments.

5 Comments

this solution is skipping html values if there are multiple occurences of same intent in the data array. for eg it considered html for only one occurence of the intent order
please help me with this. your solution is working otherwise
it was giving me { "Date": "Wed Jan 15 2020 00:00:00 GMT+0530 (India Standard Time)", "keywords" : "delivery,orders", "html" : "<h1>Delivered</h1><h1>What is the order status</h1>" instead of { "Date": "Wed Jan 15 2020 00:00:00 GMT+0530 (India Standard Time)", "keywords" : "delivery,orders", "html" : "<h1>Delivered</h1><h1>What is the order status</h1><h1>Where is my order</h1>" } }
instead of res => <h1>${res.heading}</h1>).join('') can you show me a way such that I can pass the data to the generatehtml function and then include that value in accumulator.html ?
because my heading can be like this also : '[{\"type\": \"head\", \"text\": \"This is a heading\"},\"type\": \"paragraph\", \"text\": \"This is a para\"}]' which I will parse in the generatehtml function and return the html
0

Here is what you could potentially do.

you can simplify your for loop with following code snippet

finalresult.forEach((val) => {
  const output = {};
  output['Date'] = val.Date;
  const intents = [];
  const htmls = [];
  val.data.forEach((obj) => {
    intents.push(obj.intent);
    htmls.push(`<h1>${obj.result[0].heading}</h1>`)
  });
  output.keywords = intents.join(',');
  output.html = htmls.join('');
  result.push(output);
});

var finalresult = [{
  "Date": "Wed Jan 15 2020 00:00:00 GMT+0530 (India Standard Time)",
  "data": [{
      "intent": "delivery",
      "result": [{
        "heading": "Delivered",
      }]
    },
    {
      "intent": "orders",
      "result": [{
        "heading": "What is the order status"
      }]
    },
    {
      "intent": "orders",
      "result": [{
        "heading": "Where is my order"
      }]
    }
  ]
}, {
  "Date": "Wed Jan 17 2020 00:00:00 GMT+0530 (India Standard Time)",
  "data": [{
      "intent": "feedback",
      "result": [{
        "heading": "Hello",
      }]
    },
    {
      "intent": "feedback",
      "result": [{
        "heading": "You are good"
      }]
    },
    {
      "intent": "picnic",
      "result": [{
        "heading": "Lets go on picnic"
      }]
    },
    {
      "intent": "picnic",
      "result": [{
        "heading": "Are you coming for the picnic?"
      }]
    },
    {
      "intent": "order",
      "result": [{
        "heading": "When should I pick my order"
      }]
    }
  ]
}];


const result = [];
finalresult.forEach((val) => {
  const output = {};
  output['Date'] = val.Date;
  const intents = [];
  const htmls = [];
  val.data.forEach((obj) => {
    intents.push(obj.intent);
    htmls.push(`<h1>${obj.result[0].heading}</h1>`)
  });
  output.keywords = intents.join(',');
  output.html = htmls.join('');
  result.push(output);
});

console.log(result);

Comments

0

You can use .map() to iterate over the input array and transform each object into required format:

const data = [{
  "Date":"WedJan15202000:00:00GMT+0530(IndiaStandardTime)",
  "data":[{"intent":"delivery","result":[{"heading":"Delivered",}]},{"intent":"orders","result":[{"heading":"Whatistheorderstatus"}]},{"intent":"orders","result":[{"heading":"Whereismyorder"}]}]
  }, {
  "Date":"WedJan17202000:00:00GMT+0530(IndiaStandardTime)",
  "data":[{"intent":"feedback","result":[{"heading":"Hello",}]},{"intent":"feedback","result":[{"heading":"Youaregood"}]},{"intent":"picnic","result":[{"heading":"Letsgoonpicnic"}]},{"intent":"picnic","result":[{"heading":"Areyoucomingforthepicnic?"}]},{"intent":"order","result":[{"heading":"WhenshouldIpickmyorder"}]}]
}];

const result = data.map(o => ({
  Date: o.Date,
  keywords: [...new Set(o.data.map(({ intent }) => intent))],
  html: `<h1>${[].concat(...o.data.map(({ result }) => result))
                                  .map(({ heading }) => heading)
                                  .join("</h1>")}</h1>`
}));

console.log(result);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.