0

Server gives me next array :

let reportsInDB = [
  {comment:"asdasd", date:"13-02-2018", issueId:"1005"},
  {comment:"asdasd", date:"14-02-2018", issueId:"1005"},
  {comment:"asdasd", date:"15-02-2018", issueId:"1005"},
  {comment:"qwe", date:"13-02-2018", issueId:"1006"},
  {comment:"asd123123asd", date:"14-02-2018", issueId:"1006"},
  {comment:"asd123123asd", date:"15-02-2018", issueId:"1006"},
  {comment:"lalala", date:"15-02-2018", issueId:"1007"},
]

Is there a way to make next:

compare if object with today date has same comment as the "yesterday" object (of course same issueId of that objects) and push it (maybe push not whole object, just it issueId) to new array, arrRisk = [] for example, but if comments are same 3 days in a row - push to another array, arrIncident = [], for example.

So the final output should be something like next:

arrRisk = ["1006"]
arrIncident = ["1005]

Object with issueId 1007 shouldnt go to any of new arrays, because there is no same comment with its issueId yesterday or day before yesterday.

Also I got service variables, which should help to compare:

today = "15-02-2018"
yesterday = "14-02-2018"
beforeYesterday = "13-02-2018"

I was trying something like

reportsInDB.map(x => {
    reportsInDB.map(r =>{
    if( x.date === today && 
        r.date === yesterday && 
        x.issueId === r.issueId && 
        x.comment === r.comment
    ){
        reportsToRisk.push(r)
    } 
  })
})

But output totally not what I need (e.g. I don`t need issueId 1005 push to riskArray) and double-triple cycles are not so good as I know...

That is what I try in jsfiddle

Hope my explanation what final result should be is clear.

The way of sort that comes from server: enter image description here

6
  • 1
    If there's no return when using .map() then .map() is the wrong method Commented Feb 15, 2018 at 16:07
  • @Andreas I understand.. I used map() just for looping.. Commented Feb 15, 2018 at 16:08
  • .reduce is the way to go. Do you need help writing it? Commented Feb 15, 2018 at 16:18
  • @Andrew I think to the side of .reduce but can`t get how to implement it, so it would be greate if you will help ! Commented Feb 15, 2018 at 16:23
  • Is your data guaranteed to be sorted by issueId and date? Commented Feb 15, 2018 at 17:07

2 Answers 2

2

You need to take care that the same comment for another issue will not play a role. Here is a solution that first groups the data by issue, and then collects the comments per issue. Then it is straightforward. This also does not rely on a certain sort order:

const reportsToRisk = [];
const reportsToIncident = [];
const tdy = moment().format('DD-MM-YYYY');
const yst = moment().subtract(1, 'day').format('DD-MM-YYYY');
const dby = moment().subtract(2, 'day').format('DD-MM-YYYY');
const reportsInDB = [
    {comment:"asdasd", date: dby, issueId:"1005"},
    {comment:"asdasd", date: yst, issueId:"1005"},
    {comment:"asdasd", date: tdy, issueId:"1005"},
    {comment:"qwe", date: dby, issueId:"1006"},
    {comment:"asd123123asd", date: yst, issueId:"1006"},
    {comment:"asd123123asd", date: tdy, issueId:"1006"},
    {comment:"123d", date: tdy, issueId:"1007"},
];

// create a map keyed by issueId:
const map = new Map(reportsInDB.map( report => [report.issueId, {}] ));
// Fill the date / comment pairs
for (const report of reportsInDB) {
    map.set(report.issueId, Object.assign(map.get(report.issueId), 
            { [report.date]: report.comment }));
}
for (const [issueId, comments] of map.entries()) {
    if (comments[tdy] === comments[yst]) {
        if (comments[tdy] === comments[dby]) {
            reportsToIncident.push(issueId);
        } else {
            reportsToRisk.push(issueId);
        }
    }
}
//console.log("reportsInDB", reportsInDB)
console.log('reportsToRisk', reportsToRisk)
console.log('reportsToIncident', reportsToIncident)        
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.0/moment.min.js"></script>

Sign up to request clarification or add additional context in comments.

Comments

1

Use .reduce to repeatedly compare against previous entry. Notice that I use reportsInDB.slice(1) as my array that I .reduce.That makes the variable respostInDB[idx] always point to the previous entry in the array.

After that, run a loop to check for repeats in that new array. Repeats means you have 2 incidents in a row.

After that, I have to .filter to remove ids in arrRisk that also exist in arrIncident.

let reportsInDB = [
  {comment:"asdassd", date:"13-02-2018", issueId:"1005"},
  {comment:"asdasd", date:"14-02-2018", issueId:"1005"},
  {comment:"asdasd", date:"15-02-2018", issueId:"1005"},
  {comment:"qwe", date:"13-02-2018", issueId:"1006"},
  {comment:"asd123123asd", date:"14-02-2018", issueId:"1006"},
  {comment:"asd123123asd", date:"15-02-2018", issueId:"1006"},
  {comment:"lalala", date:"14-02-2018", issueId:"1007"},
  {comment:"lalala", date:"15-02-2018", issueId:"1007"},
  {comment:"lalala", date:"15-02-2018", issueId:"1007"}
]
const matches = reportsInDB.slice(1).reduce((acc, obj, idx) => {
  if (reportsInDB[idx].comment === obj.comment) {
    return acc.concat([obj.issueId])
  } else {
    return acc
  }
}, [])

let arrRisk = []
let arrIncident = []
for (let i = 0; i < matches.length; i++) {
  if (matches[i + 1] === matches[i]) {
    arrIncident.push(matches[i])
  } else {
    arrRisk.push(matches[i])
  }
}
arrRisk = arrRisk.filter((id) => !arrIncident.includes(id))
const issues = {arrRisk, arrIncident}
console.log(issues)

2 Comments

Thank you very much! But when I change the array - there is no expected result. E.g. fiddle. in arrRisk should be issues 1005,1006 and 1007, but only 1006 and 1007 are there.. And another fiddle issue 1007 doubles in both arrays Incident and Risks.. Mb you have any ideas why?
I think it is just what I need! Thanks!

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.