0

Background

I am creating an app where users can submit a post at any time. One of the main feature of the app is that users in a group can start a session to vote for the best posts, within a period of time (e.g. all post from the last 10 days).

The app then presents the posts in a table view. Users can change the type of posts displayed using a segmented control. Once all users have voted, then the next view controller will display the result of the vote - showing only the top 5 posts for each category ("well", "notWell", "confused")

This is how I have structured it in Firebase Database.

  • Each user must belong to a group - e.g. "Balance Banana".
  • Every post must belong to one of three category - e.g. "well", "notWell", "confused".
  • Each post must have a date.

enter image description here

Question

How should I develop the feature to "display top 5 posts for each category"?

I need to retrieve 5 post with the highest vote count for each post type where date is > x.

I have looked at the several questions on SO relating to querying multiple where clauses with Firebase Database and I think the most suitable approach is to use the QueryOrderedBy to filter the date, then code the logic to extract the top 5 posts within each category. If this is a suitable approach, how should I go about iterating through each snapshot.children and create a dictionary of top 5 posts for each category?

SO Posts related to multiple where clause in Firebase Database.

Query based on multiple where clauses in firebase has an excellent answer by Frank van Puffelen relating to this topic.

Current code

func loadData() {

    self.ref.child("session").child((self.currentUser?.team)!).queryOrdered(byChild: "date").queryStarting(atValue: postStartDate).observe(.value, with: {
        snapshot in

        var wellItems: [SessionPost] = []
        var notWellItems: [SessionPost] = []
        var confusedItems: [SessionPost] = []

        for item in snapshot.children {
            let postItem = SessionPost(snapshot: item as! DataSnapshot)
            if let postType = postItem.type {
                switch postType {
                case "well":
                    wellItems.append(postItem)
                case "notWell":
                    notWellItems.append(postItem)
                case "confused":
                    confusedItems.append(postItem)
                default:
                    break
                }
            }
        }

        self.topWellPostItems = wellItems
        self.topNotWellPostItems = notWellItems
        self.topConfusedPostItems = confusedItems
        self.tableView.reloadData()
    })
J100
  • 3,896
  • 2
  • 11
  • 18

1 Answers1

0

For each of your SessionPost arrays you would have to sort based on voteCount. Such as

wellItems.sort(by: { $0.voteCount > $1.voteCount })
topFiveItems = Array(wellItems.sort[0 ..< 5])
Jože Ws
  • 1,754
  • 17
  • 12
  • Thanks @jože-ws. Firstly, SessionPost is a dictionary. I managed to sort the items based on voteCount using wellItems.sorted(by: { $0.voteCount! > $1.voteCount!} ). But how do I limit the maximum number of items in topWellPostItems to only 3? – J100 Nov 11 '17 at 06:02
  • @Jason100. Great. If this answer the question, mark it as an answer then – Jože Ws Nov 11 '17 at 06:04
  • I still haven't been able to limit the number of items in the dictionary. Any advice? – J100 Nov 11 '17 at 06:06
  • For that you will need to slice the array and get the first five items. Check out the edits – Jože Ws Nov 11 '17 at 06:10
  • Unfortunately it's a dictionary. How should I go about slicing a dictionary? – J100 Nov 11 '17 at 06:23
  • how can topWellPostItems be a dictionary and wellItems be an array. You are assigning one to the other – Jože Ws Nov 11 '17 at 06:27
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/158748/discussion-between-jason100-and-joze-ws). – J100 Nov 11 '17 at 06:28