0

How to combine object values from separate lines into one line?

If there is no matching "IN" line after "OUT", "OUT" date should be automatically closed after 1 hour. Car and user needs to be checked for a match before combining lines.

var carData = [
    {date:"2018-06-08 13:20:00", type:"OUT", car:"Car1", user:"User1"},
    {date:"2018-06-08 14:13:00", type:"IN", car:"Car1", user:"User1"},
    {date:"2018-06-08 14:20:00", type:"OUT", car:"Car2", user:"User2"},
    {date:"2018-06-08 14:20:00", type:"OUT", car:"Car3", user:"User4"},
    {date:"2018-06-08 14:35:00", type:"IN", car:"Car2", user:"User2"},
    {date:"2018-06-09 11:12:00", type:"OUT", car:"Car1", user:"User1"},
    {date:"2018-06-09 12:13:00", type:"IN", car:"Car1", user:"User1"},
    {date:"2018-06-10 17:12:00", type:"OUT", car:"Car1", user:"User3"},
    {date:"2018-06-10 18:13:00", type:"IN", car:"Car1", user:"User3"},
    {date:"2018-06-10 19:12:00", type:"OUT", car:"Car2", user:"User1"},
    {date:"2018-06-10 20:13:00", type:"IN", car:"Car2", user:"User1"}
];

Result should look like this:

var carDataCombined = [
    {dateOut:"2018-06-08 13:20:00", dateIn:"2018-06-08 14:13:00", car:"Car1", user:"User1"},
    {dateOut:"2018-06-08 14:20:00", dateIn:"2018-06-08 14:35:00", car:"Car2", user:"User2"},
    {dateOut:"2018-06-08 14:20:00", dateIn:"2018-06-08 15:20:00", car:"Car3", user:"User4"},
    {dateOut:"2018-06-09 11:12:00", dateIn:"2018-06-09 12:13:00", car:"Car1", user:"User1"},
    {dateOut:"2018-06-10 17:12:00", dateIn:"2018-06-10 18:13:00", car:"Car1", user:"User3"},
    {dateOut:"2018-06-10 19:12:00", dateIn:"2018-06-10 20:13:00", car:"Car2", user:"User1"},
];
str
  • 42,689
  • 17
  • 109
  • 127
Mika2salo
  • 37
  • 5
  • 6
    Please post a [mcve] of your attempt at solving the problem, as an [edit] to your question, and say specifically where you're stuck. – Luca Kiebel Sep 18 '18 at 11:05
  • Please read [What is the difference between JSON and Object Literal Notation?](https://stackoverflow.com/questions/2904131/what-is-the-difference-between-json-and-object-literal-notation) There is no JSON in your question. – str Sep 18 '18 at 11:13
  • 1
    Possible duplicate of https://stackoverflow.com/questions/30093561/merge-two-json-object-based-on-key-value-in-javascript – Kamesh Sep 18 '18 at 11:23

3 Answers3

0

I think, this could be your solution:

var carData = [
    {date:"2018-06-08 13:20:00", type:"OUT", car:"Car1", user:"User1"},
    {date:"2018-06-08 14:13:00", type:"IN", car:"Car1", user:"User1"},
    {date:"2018-06-08 14:20:00", type:"OUT", car:"Car2", user:"User2"},
    {date:"2018-06-08 14:20:00", type:"OUT", car:"Car3", user:"User4"},
    {date:"2018-06-08 14:35:00", type:"IN", car:"Car2", user:"User2"},
    {date:"2018-06-09 11:12:00", type:"OUT", car:"Car1", user:"User1"},
    {date:"2018-06-09 12:13:00", type:"IN", car:"Car1", user:"User1"},
    {date:"2018-06-10 17:12:00", type:"OUT", car:"Car1", user:"User3"},
    {date:"2018-06-10 18:13:00", type:"IN", car:"Car1", user:"User3"},
    {date:"2018-06-10 19:12:00", type:"OUT", car:"Car2", user:"User1"},
    {date:"2018-06-10 20:13:00", type:"IN", car:"Car2", user:"User1"}
];

var carDataCombined = [];

function addOneHour(date){
  date = new Date(date);
  date.setHours(date.getHours() + 1);
  var hours = (date.getHours() < 10) ? '0' + date.getHours() : date.getHours();
  var minutes = (date.getMinutes() < 10) ? '0' + date.getMinutes() : date.getMinutes();
  var seconds = (date.getSeconds() < 10) ? '0' + date.getSeconds() : date.getSeconds();
  return date.toISOString().substring(0, 10) + ' ' + hours + ':' + minutes + ':' + seconds;
}

for(var i = 0; i < carData.length; i++){
  if(carData[i].type === 'OUT'){
    var dateIn;
    if(carData[i+1] && carData[i+1].type === 'IN' && (carData[i].car === carData[i+1].car && carData[i].user === carData[i+1].user)){
      dateIn = carData[i+1].date;
    } else {
      dateIn = addOneHour(carData[i].date)
    }
    carDataCombined.push({dateOut: carData[i].date, dateIn: dateIn, car: carData[i].car, user: carData[i].user});
  }
}

console.log(carDataCombined)
jsadev.net
  • 2,800
  • 1
  • 16
  • 28
0

The below logic should work

  • loop carData with $.each only which type is of OUT
  • Check if next record exist,
  • If yes get the record
  • else form new date from OUT date and add 1 hour to it.

var carData = [{
        date: "2018-06-08 13:20:00",
        type: "OUT",
        car: "Car1",
        user: "User1"
    },
    {
        date: "2018-06-08 14:13:00",
        type: "IN",
        car: "Car1",
        user: "User1"
    },
    {
        date: "2018-06-08 14:20:00",
        type: "OUT",
        car: "Car2",
        user: "User2"
    },
    {
        date: "2018-06-08 14:20:00",
        type: "OUT",
        car: "Car3",
        user: "User4"
    },
    {
        date: "2018-06-08 14:35:00",
        type: "IN",
        car: "Car2",
        user: "User2"
    },
    {
        date: "2018-06-09 11:12:00",
        type: "OUT",
        car: "Car1",
        user: "User1"
    },
    {
        date: "2018-06-09 12:13:00",
        type: "IN",
        car: "Car1",
        user: "User1"
    },
    {
        date: "2018-06-10 17:12:00",
        type: "OUT",
        car: "Car1",
        user: "User3"
    },
    {
        date: "2018-06-10 18:13:00",
        type: "IN",
        car: "Car1",
        user: "User3"
    },
    {
        date: "2018-06-10 19:12:00",
        type: "OUT",
        car: "Car2",
        user: "User1"
    },
    {
        date: "2018-06-10 20:13:00",
        type: "IN",
        car: "Car2",
        user: "User1"
    }
];

var carDataCombined;
var carDataCombinedArray = [];
var i = 0;
$(function() {

    $(carData).each(function(key, item) {
        if (item.type == "IN") return;

        var currentItem = item;
        var nextItem = key !== carData.length - 1 ? carData[key + 1] : null

        var dateOut = item.date;
        var dateIn = nextItem && nextItem.type == "IN" ? nextItem.date : null;
        var car = item.car;
        var user = item.user;

        if (!dateIn) {
            var d = new Date(dateOut);
            dateIn = (
                d.getFullYear() + "-" + ("00" + d.getMonth()).slice(-2) + "-" + ("00" + d.getDate()).slice(-2) + " " +
                ("00" + (d.getHours() + 1)).slice(-2) + ":" + ("00" + d.getMinutes()).slice(-2) + ":" + ("00" + d.getSeconds()).slice(-2));

        }

        carDataCombinedArray.push({
            "dateOut": dateOut,
            "dateIn": dateIn,
            "car": car,
            "user": user,
        });

         carDataCombined = JSON.stringify(carDataCombinedArray);
    });

console.log(carDataCombined);

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Hary
  • 5,690
  • 7
  • 42
  • 79
0

I'm a little late, others was faster!

The algorithm:

  • iterate the source array
  • if data type is OUT
    • find the data with the same car and user
    • if IN data was found: write the result
    • if nothing or OUT data was found: write a result with dateIn = dateOut + 1h

You may prefer J. Sadi similar answer: mine consume the input array.

let carData = [
    {date:"2018-06-08 13:20:00", type:"OUT", car:"Car1", user:"User1"},
    {date:"2018-06-08 14:13:00", type:"IN", car:"Car1", user:"User1"},
    {date:"2018-06-08 14:20:00", type:"OUT", car:"Car2", user:"User2"},
    {date:"2018-06-08 14:20:00", type:"OUT", car:"Car3", user:"User4"},
    {date:"2018-06-08 14:35:00", type:"IN", car:"Car2", user:"User2"},
    {date:"2018-06-09 11:12:00", type:"OUT", car:"Car1", user:"User1"},
    {date:"2018-06-09 12:13:00", type:"IN", car:"Car1", user:"User1"},
    {date:"2018-06-10 17:12:00", type:"OUT", car:"Car1", user:"User3"},
    {date:"2018-06-10 18:13:00", type:"IN", car:"Car1", user:"User3"},
    {date:"2018-06-10 19:12:00", type:"OUT", car:"Car2", user:"User1"},
    {date:"2018-06-10 20:13:00", type:"IN", car:"Car2", user:"User1"}
];

// can be simplified with momentjs functions...
function add1Hour(strDate) {
  let timestamp = Date.parse(strDate.replace(' ', 'T'));
  let isoData = new Date(timestamp + 3600 * 1000).toISOString();
  return isoData.replace(/(.*)T(.*)\..*/, '$1 $2');
}

let carDataCombined = [];

while (carData.length > 0) {
  let data = carData.shift();

  if (data.type === 'OUT') {
    let nextData = carData.find((otherData) => (otherData.car === data.car && otherData.user === data.user))
    let dateIn;
    if (nextData === undefined || nextData.type === 'OUT')
      dateIn = add1Hour(data.date);
    else
      dateIn = nextData.date
    carDataCombined.push({ dateOut: data.date, dateIn: dateIn, car: data.car, user: data.user });
  }
}

console.log(carDataCombined);
Ek1noX
  • 443
  • 6
  • 11