1

I have a nested map to iterate through my data and then return a react component for each object I have in my Data. Check the code below:

return props.dataArray.map((classObj) => {
                    return classObj.timetable.map((timetableObj) => {
                        if (timetableObj.weekday === props.day) {
                            return ttCard({
                                lecturer: classObj.lecturer,
                                module: classObj.module,
                                room: classObj.room,
                                class_id: classObj.id,
                                timetable_id: timetableObj.id,
                                startTime: timetableObj.start_time,
                                endTime: timetableObj.end_time,
                                weekday: timetableObj.weekday
                            });
                        }
                        return null;
                    });
                });

My issue is that my component aren't sorted and they have to be sorted because it is a timetable for students. Look at the image below and notice how 10:30 AM is the latest card in my tab view:

enter image description here

things I tried so far:

1- creating a new array then sorting it after the if statement block - not working 2- returning a sorted array to a function and mapping that array to return the component - not working 3- looping and returning the object as a function within the component parameter:

ttCard( sortedArr.forEach((ttObject) => {
return ttObject
}))

also not working

I have googled and tried to research but no hope so far. I know that initially my nested map is bad but this is how my object looks like:

[
    {
        "class_code": "English-5-G-2-L-1911-test-teacher",
        "id": 23,
        "lecturer": "test teacher",
        "module": "English-5",
        "room": "L",
        "timetable": [
            {
                "end_time": "9:00",
                "id": 37,
                "start_time": "8:00",
                "weekday": "Sunday"
            },
            {
                "end_time": "10:00",
                "id": 38,
                "start_time": "9:00",
                "weekday": "Sunday"
            },
            {
                "end_time": "10:00",
                "id": 47,
                "start_time": "9:00",
                "weekday": "Monday"
            },
            {
                "end_time": "10:00",
                "id": 48,
                "start_time": "9:00",
                "weekday": "Tuesday"
            },
            {
                "end_time": "11:30",
                "id": 52,
                "start_time": "10:30",
                "weekday": "Tuesday"
            },
            {
                "end_time": "11:30",
                "id": 54,
                "start_time": "10:30",
                "weekday": "Thursday"
            },
            {
                "end_time": "12:30",
                "id": 58,
                "start_time": "11:30",
                "weekday": "Thursday"
            },
            {
                "end_time": "14:00",
                "id": 61,
                "start_time": "13:00",
                "weekday": "Wednesday"
            }
        ]
    }
]
2
  • Can you sort them in the parent component instead, seeing as they are props? If not, would you consider sorting them in the constrcutor and storing the sorted results in this.state? Because sorting them EVERY RENDER seems awfully bad for performance to me Commented Dec 20, 2019 at 17:05
  • Sort & Map will work as expected,.. Problem is your not showing this code, so it's hard to suggest were you went wrong. Also when sorting your times, think about 0 padding the times, as 9:00 is after 11:20 in string sort.. but 09:00 is not. Commented Dec 20, 2019 at 17:07

1 Answer 1

2

You can use sort on your output to arrange the array by startTime

.sort((a, b) => {
    // These lines are so we can directly compare the times
    // I would recommend to send timestamps down with your data (if possible)
    var aTime = a.startTime.replace(':', '');
    var bTime = b.startTime.replace(':', '');

    // Sort by smallest first
    return aTime - bTime;
  });

I would also suggest filtering out null values in your array

Using your example -

var classesArr = props.dataArray.map((classObj) => {
  return classObj.timetable.map((timetableObj) => {
    if (timetableObj.weekday === props.day) {
      return {
        lecturer: classObj.lecturer,
        module: classObj.module,
        room: classObj.room,
        class_id: classObj.id,
        timetable_id: timetableObj.id,
        startTime: timetableObj.start_time,
        endTime: timetableObj.end_time,
        weekday: timetableObj.weekday
      }
    }
    return null;
  }).filter(x => x); // Filter out any null values
}).filter(x => x); // Filter out any null values.

// Flatten array so it is sortable/mapable
return [].concat.apply([], classesArr).sort((a, b) => {
  // These lines are so we can directly compare the times
  // I would recommend to send timestamps down with your data (if possible)
  var aTime = a.startTime.replace(':', '');
  var bTime = b.startTime.replace(':', '');
  // Sort by smallest time first
  return aTime - bTime;
}).map((x) => {
  return ttCard(x);
})
Sign up to request clarification or add additional context in comments.

9 Comments

Hey, I tried your answer but it is not working, i parsed it into an int but still. Any other solutions?
@ZyzzShembesh My bad, I have updated the sort now to use return aTime - bTime; Tested with your array and it works :)
Hey, thank you again for your help, I tried it again and it is still not working :(. did you see how my data looks like above?
Can you please explain what you mean by "not working"? Here is a JSFiddle showing the sort working jsfiddle.net/phmq230r
basically my list comes out the same. 10:30 is still the last card. sorry for late reply but i had issues with my ISP. this Js fiddle contains my whole data list. can you try and display classes in timetable that are on a Sunday only and sorted? jsfiddle.net/oymz8h4w
|

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.