2

I have an array with a bunch of objects in it. The 'endTime' value of one object is sometimes greater than the 'endTime' value of the previous one. I have added an example of this within the second object in the array.

[
  { 
    title: 'Title 1',
    startTime: '2019-09-26T06:00:00+0100',
    endTime: '2019-09-26T08:30:00+0100' 
  },
  { 
    title: 'Title 2',
    startTime: '2019-09-26T08:00:00+0100',
    endTime: '2019-09-26T08:15:00+0100' 
  },
  { 
    title: 'Title 3',
    startTime: '2019-09-26T08:30:00+0100',
    endTime: '2019-09-26T09:25:00+0100' 
  },
  { 
    title: 'Title 4',
    startTime: '2019-09-26T09:25:00+0100',
    endTime: '2019-09-26T10:25:00+0100' 
  },
  { 
    title: 'Title 5',
    startTime: '2019-09-26T10:25:00+0100',
    endTime: '2019-09-26T11:00:00+0100' 
  }
]

The 'endTime' should aways be chronological and '8:15' should never come after '8:30' in the array. I'm looking to do a check for whenever 'endTime' value is less than it's previous and then remove it from the array. Any help would be appreciated. Thanks

5
  • Do you want to remove the one with 8:30 or the one with 8:15? Commented Sep 26, 2019 at 10:35
  • @briosheje i'd be looking to remove whenever the endTime is less than the previous object, so in this case, yeah it'd be the 8:15 one Commented Sep 26, 2019 at 10:48
  • @ramageftw do you want it removed when the end time is less than the previous object or less than all the previous objects? Commented Sep 26, 2019 at 11:00
  • @JamesCoyle just when it's less than the previous object. thats the use case in this situation Commented Sep 26, 2019 at 11:15
  • @ramageftw I've updated my answer to include both methods anyway. Commented Sep 26, 2019 at 11:26

3 Answers 3

1

Here are two methods. The first returns the array where items are only compared to the previous object in the array. The second compares the item to all objects before the current one in the array.

const data = [{
    title: 'Title 1',
    startTime: '2019-09-26T06:00:00+0100',
    endTime: '2019-09-26T08:30:00+0100'
  },
  {
    title: 'Title 2',
    startTime: '2019-09-26T08:00:00+0100',
    endTime: '2019-09-26T08:15:00+0100'
  },
  {
    title: 'Title 3',
    startTime: '2019-09-26T08:30:00+0100',
    endTime: '2019-09-26T09:25:00+0100'
  },
  {
    title: 'Title 4',
    startTime: '2019-09-26T09:25:00+0100',
    endTime: '2019-09-26T10:25:00+0100'
  },
  {
    title: 'Title 5',
    startTime: '2019-09-26T10:25:00+0100',
    endTime: '2019-09-26T11:00:00+0100'
  }
].map(item => {
  item.startTime = new Date(item.startTime)
  item.endTime = new Date(item.endTime)
  return item
})

const greaterThanLast = data.filter((item, index) => {
  const last = data[index - 1]
  if (typeof last == 'undefined') return true
  return item.endTime > last.endTime
})

const greaterThanAll = data.reduce((result, current) => {
  const endTimeGreaterThanRest = result.every((item) => current.endTime > item.endTime)
  if (endTimeGreaterThanRest) result.push(current)
  return result
}, [])

console.log(greaterThanLast)
console.log(greaterThanAll)

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

3 Comments

Note that your result comes out with start/endTime changed from string to date.
Good point. You could easily convert the date within the filter/reduce itself if that is important. I'm just converting ahead of time for convenience and to make the actual functions clearer to read.
Works a dream. Cheers!
1

Assuming you don't want to alter the original array and assuming you want to remove the "lowest" value, you could do a single for loop that will:

  • Keep track of the previous value.
  • Compare the previous value with the current one.
  • Filter the value according to your needs.

Comments about the code are directly below, this solution implies looping the original array only once, taking advantage of a single for-of loop.

const input = [
  { 
    title: 'Title 1',
    startTime: '2019-09-26T06:00:00+0100',
    endTime: '2019-09-26T08:30:00+0100' 
  },
  { 
    title: 'Title 2',
    startTime: '2019-09-26T08:00:00+0100',
    endTime: '2019-09-26T08:15:00+0100' 
  },
  { 
    title: 'Title 3',
    startTime: '2019-09-26T08:30:00+0100',
    endTime: '2019-09-26T09:25:00+0100' 
  },
  { 
    title: 'Title 4',
    startTime: '2019-09-26T09:25:00+0100',
    endTime: '2019-09-26T10:25:00+0100' 
  },
  { 
    title: 'Title 5',
    startTime: '2019-09-26T10:25:00+0100',
    endTime: '2019-09-26T11:00:00+0100' 
  }
];

function fixChronologicalItems(arr) {
  // Keep track of the previous item.
  let res = [], previous;
  // Iterate all the items of the array.
  for (let i = 0; i < arr.length; i++) {
    // assume the current item is the looped one.
    let item = arr[i];
    // if our accumulator is not empty, acquire its last element considering it the previous item.
    if (res[res.length - 1]) previous = res[res.length - 1];
    else previous = arr[i], item = arr[i+1], i++; // if it doesn't, consider the current item the previous one, and the current item the next one, so increase the index by one to properly skip the next item.
    // Acquire both datetimes.
    let [previousDate, nextDate] = [new Date(previous.endTime), new Date(item.endTime)];
    // if the previous item's date is before the next one, both items should be kept.
    if (previousDate < nextDate) {
      res.push(item); // <-- this will become the next "previous".
    }
    else res.push(previous); // <-- Otherwise, only the greatest date (which is the previous one) should be kept.
  }
  // finally, return the accumulator.
  return res;
}
const res = fixChronologicalItems(input);
console.log(res);

Comments

0

James Coyle's answer is way smoother than mine, but here is my take on things.

In my solution I check to see if the next value is less than the current value, if so, then remove it from the array using delete.

If we get to the last value in the array, then we no longer need to check the next item, so then we don't enter the if statement and break the loop.

var dataset = [{
    title: 'Title 1',
    startTime: '2019-09-26T06:00:00+0100',
    endTime: '2019-09-26T08:30:00+0100'
  },
  {
    title: 'Title 2',
    startTime: '2019-09-26T08:00:00+0100',
    endTime: '2019-09-26T08:15:00+0100'
  },
  {
    title: 'Title 3',
    startTime: '2019-09-26T08:30:00+0100',
    endTime: '2019-09-26T09:25:00+0100'
  },
  {
    title: 'Title 4',
    startTime: '2019-09-26T09:25:00+0100',
    endTime: '2019-09-26T10:25:00+0100'
  },
  {
    title: 'Title 5',
    startTime: '2019-09-26T10:25:00+0100',
    endTime: '2019-09-26T11:00:00+0100'
  }
]

var lengthOfArray = dataset.length;
for (i = 0; i < dataset.length; i++) {
  if (lengthOfArray !== i + 1) {
    var dt = new Date(dataset[i].endTime),
    dt2 = new Date(dataset[i + 1].endTime);
    if (dt2 < dt) delete dataset[i + 1].endTime;
  }
  else {
    break;
  }
}
console.log(dataset);

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.