0

As I mentioned in the title, I have a list of JavaScript objects which has following structure:

[
    {value: 1, date: timestamp},
    {value: 1, date: timestamp + 1},
    {value: 0, date: timestamp + 2}
]

Is there a way to skip every object with the same value as previous one? Value can only be either 1 or 0. I was thinking about some mix of filter or reduce/compare.

The result would be as follows:

[
    {value: 1, date: timestamp},
    {value: 0, date: timestamp + 2}
]
steve1337
  • 377
  • 1
  • 8

6 Answers6

1

Please try the following

const newObjects = objects.reduce((cur, obj) => {
  if (!cur.length || obj.value !== cur[cur.length - 1].length) {
     cur.push(obj);
  }
  return cur;
}, []);
SoftDev
  • 559
  • 2
  • 8
1

Using filter with remeber the last value.

let timestamp = 0;
let arr = [
    {value: 1, date: timestamp},
    {value: 1, date: timestamp + 1},
    {value: 0, date: timestamp + 2},
    {value: 1, date: timestamp + 32},
    {value: 1, date: timestamp + 4}
];

let last = null;
let result = arr.filter(obj => {
    if (obj.value===last) {
        return false
    } else {
        last = obj.value;
        return true;
    }
});

console.log(result);
Sascha
  • 4,576
  • 3
  • 13
  • 34
0

As you're iterating you just need to remember the value of the previous item. If it matches, you just keep going. So something like this:

skipEveryOther(input_arr){
    let prevVal=null;
    const toReturn=[]
    for(let i=0; i<input_arr.length; i+=1){
        const curObj=input_arr[i];
        if(curObj.value!=prevVal){
           toReturn.push(curObj);
           prevVal=curObj.value;
        }
    }
    return toReturn;
}
code11
  • 1,986
  • 5
  • 29
  • 37
0

Really unreadable way of doing it with reduce.

var data = [
    {value: 1, date: 0},
    {value: 1, date: 1},
    {value: 0, date: 2}
]

const cleaned =
  data.reduce( 
    (obj, record) => (
      !obj.s[record.value] && 
      (obj.s[record.value] = 1) && 
      obj.a.push(record), 
      obj)
, {s:{}, a: []}).a;

console.log(cleaned)

The code in a more readable format

var data = [
    {value: 1, date: 0},
    {value: 1, date: 1},
    {value: 0, date: 2}
]

const cleaned =
  data.reduce( 
    (obj, record) => {
      if (!obj.seen[record.value]) { 
          obj.seen[record.value] = 1;
          obj.array.push(record);
      }
      return obj;
}, { seen: {}, array: [] }).array;

console.log(cleaned)
epascarello
  • 204,599
  • 20
  • 195
  • 236
0

A simple .map() might do the trick:

const arr = [{
    value: 1,
    date: timestamp
  },
  {
    value: 1,
    date: timestamp + 1
  },
  {
    value: 0,
    date: timestamp + 2
  }
];

arr.map((n, index) => {
  if (
    !arr[index - 1] || // if there is NOT an element behind us
    n.value !== arr[index - 1].value // compare the current element to the one before it
  ) {
    console.log(n)
  }
})

foxtrotuniform6969
  • 3,527
  • 7
  • 28
  • 54
0

Just filter with the last value.

const
    timestamp = '',
    data = [{ value: 1, date: timestamp }, { value: 1, date: timestamp + 1 }, { value: 0, date: timestamp + 2 }],
    result = data.filter(({ value }, i, { [i - 1]: { value: last } = {} }) => value !== last);

console.log(result);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392