0

I wish to retrieve hall and its length from the result. Unfortunately, I am not able to retrieve it out and it shows undefined.

These are data:

{
  "result": {
    "Hall 0": [
      {
        "lectureID": "1110000001",
        "startTime": "08:30:00",
        "endTime": "10:30:00"
      },
      {
        "lectureID": "1110000002",
        "startTime": "12:30:00",
        "endTime": "14:00:00"
      },
      {
        "lectureID": "1110000004",
        "startTime": "14:00:00",
        "endTime": "16:00:00"
      }
    ],

    "Hall 1": [
      {
        "lectureID": "1110000003",
        "startTime": "08:00:00",
        "endTime": "09:00:00"
      }
    ],
    "Hall 2": [
      {
        "lectureID": "1110000006",
        "startTime": "09:00:00",
        "endTime": "11:00:00"
      }
    ],
    "Hall 3": [
      {
        "lectureID": "1110000007",
        "startTime": "08:30:00",
        "endTime": "11:00:00"
      }
    ]

These are my codes to retrieve the elements in Hall and the hall.length :

 for (let i = 0; i < Object.keys(result).length; i++) {
        console.log("result: ",result[`Hall ${i}`]);  //this line shows undefined
        console.log(result[`Hall ${i}`].length);    //this line is undefined
        for (let j = 0; j < result[`Hall ${i}`].length; j++) {
            const lecture = result[`Hall ${i}`][j];
            const startTime = lecture.startTime;
            const endTime = lecture.endtime;
            earliestStartTime = Math.min(earliestStartTime, startTime);
            latestEndTime = Math.max(latestEndTime, endTime);
        }
    }

May I know how can I get the objects in result as well as the elements in Hall? Thank you so much!

7
  • what is the result here? In provided json (which is incorrect) all the "Halls" are under "result" entry. If you assign the whole object to "result" variable then you need to use "result.result" to access your objects Commented Jul 16, 2020 at 14:34
  • A good hint when showing data on Stack Overflow: use console.log(JSON.stringify(obj, null, 2)), then copy and paste the data into the question. Highlight it and click the {} button in the toolbar. Commented Jul 16, 2020 at 14:34
  • Does this answer your question? How can I access and process nested objects, arrays or JSON? Commented Jul 16, 2020 at 14:36
  • @HereticMonkey I have edited the codes, and the link that you provided doesn't work for this case. Commented Jul 16, 2020 at 14:44
  • @Adassko the result here is a {} computed from API Commented Jul 16, 2020 at 14:46

3 Answers 3

1

Find earliestStartTime and latestEndTime in your data. Math.min can't work with string, so you need to use custom comparison function compareTime. Use Object.values to iterate for each property and reduce to find min and max.

const toSeconds = time => {
    const a = time.split(':');
    return +a[0] * 60 * 60 + +a[1] * 60 + +a[2];
};

const compareTime = (a, b, direction) => {
    const a1 = toSeconds(a);
    const b1 = toSeconds(b);

    return direction ? (a1 > b1 ? a : b) : a1 < b1 ? a : b;
};

const result = {
    'Hall 0': [
        { lectureID: '1110000001', startTime: '08:30:00', endTime: '10:30:00' },
        { lectureID: '1110000002', startTime: '12:30:00', endTime: '14:00:00' },
    ],
    'Hall 1': [{ lectureID: '1110000003', startTime: '08:00:00', endTime: '09:00:00' }],
    'Hall 2': [{ lectureID: '1110000006', startTime: '09:00:00', endTime: '11:00:00' }],
    'Hall 3': [{ lectureID: '1110000008', startTime: '09:00:00', endTime: '12:00:00' }],
};

const res = Object.values(result).reduce(
    (acc, arr) => {
        arr.forEach(lecture => {
            const startTime = lecture.startTime;
            const endTime = lecture.endTime;
            acc.earliestStartTime = compareTime(acc.earliestStartTime, startTime, false);
            acc.latestEndTime = compareTime(acc.latestEndTime, endTime, true);
        });

        return acc;
    },
    {
        earliestStartTime: '25:00:00',
        latestEndTime: '00:00:00',
    },
);

console.log(res);

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

3 Comments

sorry, may i ask what is {earliestStartTime: '25:00:00',latestEndTime: '00:00:00',}, this part for?
@wink these are the initial (boundary) values for comparison and finding the maximum and minimum time. (second parameter for reduce)
alright! I have a better understanding now, thanks!
1

Just use Object.values to access your values as you don't use the key anyway:

Object.values(result.result)
  .map(lectures => ({
    earliestStartTime: lectures.map(x => x.startTime).reduce((x, y) => x < y ? x : y),
    latestEndTime: lectures.map(x => x.endTime).reduce((x, y) => x > y ? x : y)
  }));

var result = {
  "result": {
    "Hall 0": [
      {
        "lectureID": "1110000001",
        "startTime": "08:30:00",
        "endTime": "10:30:00"
      },
      {
        "lectureID": "1110000002",
        "startTime": "12:30:00",
        "endTime": "14:00:00"
      },
      {
        "lectureID": "1110000004",
        "startTime": "14:00:00",
        "endTime": "16:00:00"
      }
    ],
    "Hall 1": [
      {
        "lectureID": "1110000003",
        "startTime": "08:00:00",
        "endTime": "09:00:00"
      }
    ],
    "Hall 2": [
      {
        "lectureID": "1110000006",
        "startTime": "09:00:00",
        "endTime": "11:00:00"
      }
    ],
    "Hall 3": [
      {
        "lectureID": "1110000007",
        "startTime": "08:30:00",
        "endTime": "11:00:00"
      }
    ]
  }
};

var times = Object.values(result.result)
    .map(lectures => ({
      earliestStartTime: lectures.map(x => x.startTime).reduce((x, y) => x < y ? x : y),
      latestEndTime: lectures.map(x => x.endTime).reduce((x, y) => x > y ? x : y)
    }));
    
console.log(times);

3 Comments

am i able to do a for-loop here to find the earliestStartTime and latestEndTime?
sure, you can use forEach, map or reduce to iterate over objects. You can also use a normal for-loop or for-of loop for (var sth of Object.values(result)) if you don't care about Internet Explorer. Experiment by yourself or you will need to come here with every problem
Thank you so much! did lots of try of error yesterday and explored new stuff!
1

You seems to have trouble to loop over object/array, i suggest you to restart javascript basis, and look at the example below

var object = {
  "result": {
    "Hall 0": [
      {
        "lectureID": "1110000001",
        "startTime": "08:30:00",
        "endTime": "10:30:00"
      },
      {
        "lectureID": "1110000002",
        "startTime": "12:30:00",
        "endTime": "14:00:00"
      },
      {
        "lectureID": "1110000004",
        "startTime": "14:00:00",
        "endTime": "16:00:00"
      }
    ],

    "Hall 1": [
      {
        "lectureID": "1110000003",
        "startTime": "08:00:00",
        "endTime": "09:00:00"
      }
    ],
    "Hall 2": [
      {
        "lectureID": "1110000006",
        "startTime": "09:00:00",
        "endTime": "11:00:00"
      }
    ],
    "Hall 3": [
      {
        "lectureID": "1110000007",
        "startTime": "08:30:00",
        "endTime": "11:00:00"
      }
    ]}};

var result = object.result;

for (var i in result) {
      console.log(i);
      console.log(result[i]);  //this line shows undefined
      console.log(result[i].length);    //this line is undefined
      for (let j = 0; j < result[i].length; j++) {
          const lecture = result[i][j];
          console.log(lecture);
      }
  }

Or if you just want the result without understanding anything

var object = {
  "result": {
    "Hall 0": [
      {
        "lectureID": "1110000001",
        "startTime": "08:30:00",
        "endTime": "10:30:00"
      },
      {
        "lectureID": "1110000002",
        "startTime": "12:30:00",
        "endTime": "14:00:00"
      },
      {
        "lectureID": "1110000004",
        "startTime": "14:00:00",
        "endTime": "16:00:00"
      }
    ],

    "Hall 1": [
      {
        "lectureID": "1110000003",
        "startTime": "08:00:00",
        "endTime": "09:00:00"
      }
    ],
    "Hall 2": [
      {
        "lectureID": "1110000006",
        "startTime": "09:00:00",
        "endTime": "11:00:00"
      }
    ],
    "Hall 3": [
      {
        "lectureID": "1110000007",
        "startTime": "08:30:00",
        "endTime": "11:00:00"
      }
    ]}};


    var result = Object.fromEntries(
        Object.entries(
           Object.values(object.result).flat().map(function(e){

              return {
                 startTime: new Date("2020-01-01T"+e.startTime+".000Z").getTime(), 
                 endTime: new Date("2020-01-01T"+e.endTime+".000Z").getTime()};
              }

           ).reduce(function(acc, e){

             acc.earliestStartTime = Math.min(acc.earliestStartTime || e.startTime, e.startTime);
             acc.latestEndTime = Math.max(acc.latestEndTime || e.endTime, e.endTime);
             return acc;
           },
           {earliestStartTime: null, latestEndTime: null}
           )
         ).map(function(e){
           e[1] = new Date(e[1]).toJSON().substr(11, 8);
           return e;
         })
     )
    console.log(result);

3 Comments

yep! this looks fine! But still I will not able to find the earliestStartTime and latestEndTime if i use my code in this for-loop
You just have to add your logic, we're here to help, not to do the work :)
+ you can't compare string time with just a Math.min, just try Math.min("11:00:00", "11:00:01") you will see that you're result is not valid, convert your time to a date object

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.