按顺序排序数据

时间:2017-02-19 18:06:44

标签: ios swift firebase firebase-realtime-database

我有一个从Firebase获取数据的功能。功能是:

private var levelsArr = [Level]()
func fetchLevels() {

    DataService.instance.levelsRef.observe(.value, with: { (snapshot) in
        print(snapshot)
        if let lvlsDict = snapshot.value as? Dictionary<String, AnyObject> {

            for(_, valueLvl) in lvlsDict {

                if let lvlDict = valueLvl as? Dictionary<String, AnyObject> {
                    if let lvlId = lvlDict["id"] as? Int, let lvlCoverImg = lvlDict["coverImage"] as? String, let lvlTitle = lvlDict["title"] as? String {
                      let level = Level(id: lvlId, coverImage: lvlCoverImg, title: lvlTitle)
                        self.levelsArr.append(level)
                        print(self.levelsArr)
                        DispatchQueue.main.async(execute: { 
                            self.collectionView?.reloadData()
                        })

                    }
                }
            }
        }

    })
    print(self.levelsArr)
}

当我运行应用程序时,控制台会给我这个:

[Repeat.Level(id: 0, coverImage: "lvl0", title: "Level0")]
[Repeat.Level(id: 0, coverImage: "lvl0", title: "Level0"), Repeat.Level(id: 2, coverImage: "lvl2", title: "Level2")]
[Repeat.Level(id: 0, coverImage: "lvl0", title: "Level0"), Repeat.Level(id: 2, coverImage: "lvl2", title: "Level2"), Repeat.Level(id: 3, coverImage: "lvl3", title: "Level3")]
[Repeat.Level(id: 0, coverImage: "lvl0", title: "Level0"), Repeat.Level(id: 2, coverImage: "lvl2", title: "Level2"), Repeat.Level(id: 3, coverImage: "lvl3", title: "Level3"), Repeat.Level(id: 1, coverImage: "lvl1", title: "Level1")]

当我打印快照时,它是有序的,但当我获取de数据并将每个级别放入一个数组时,它不再被命令。

为什么会这样做?如何在快照中订购我的数据?

谢谢。

更新

进行以下更改:

    func fetchLevels() {
    DataService.instance.levelsRef.queryOrdered(byChild: "lvlId").observe(.value, with: { (snapshot) in
        print(snapshot)
        if let lvlsDict = snapshot.value as? Dictionary<String, AnyObject> {
            self.levelsArr.removeAll()
            for(_, valueLvl) in lvlsDict {

                if let lvlDict = valueLvl as? Dictionary<String, AnyObject> {
                    if let lvlId = lvlDict["id"] as? Int, let lvlCoverImg = lvlDict["coverImage"] as? String, let lvlTitle = lvlDict["title"] as? String {
                      let level = Level(id: lvlId, coverImage: lvlCoverImg, title: lvlTitle)
                        self.levelsArr.append(level)
                        DispatchQueue.main.async(execute: { 
                            self.collectionView?.reloadData()
                        })
                    }
                }
            }
        }

    })
}



override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        // Configure the cell

        let lvlCell = collectionView.dequeueReusableCell(withReuseIdentifier: lvlCellId, for: indexPath) as! lvlCell

        levelsReverseArr = levelsArr.reversed()

        print(levelsReverseArr)
        lvlCell.level = levelsReverseArr[indexPath.item]



        return lvlCell
    }

控制台结果:

Snap (levels) {
level0 =     {
    coverImage = lvl1;
    id = 0;
    title = Level1;
};
level1 =     {
    coverImage = lvl2;
    id = 1;
    title = Level2;
};
level2 =     {
    coverImage = lvl3;
    id = 2;
    title = Level3;
};

[Repeat.Level(id: 1, coverImage: "lvl1", title: "Level1"), Repeat.Level(id: 3, coverImage: "lvl3", title: "Level3"), Repeat.Level(id: 2, coverImage: "lvl2", title: "Level2"), Repeat.Level(id: 0, coverImage: "lvl0", title: "Level0")]

1 个答案:

答案 0 :(得分:-1)

我不完全确定为什么Firebase会喜欢乱七八糟的&#39;对于数组,所以我无法回答你问题的那一面,但为了解决问题,你可以使用.queryOrdered(byChild:)来订购快照,更改&#39; id&#39;任何可以命令你的对象的东西:

DataService.instance.levelsRef.queryOrdered(byChild: "id").observe(.value, with: { (snapshot) in

一旦数组已满或更新,您可能还需要将其反转...

更新:

希望这应该排序&#39;你的问题,如果你得到我的双关语,那就是如果等级id是一个int并且你想要它为lvl 0 ... 100订购?现在不需要.queryOrdered

func insertionSort<T>(_ arr: [T], _ isOrderedBefore: (T, T) -> Bool) -> [T] {
    guard arr.count > 1 else { return arr }

    var b = arr
    for i in 1..<b.count {
        var y = i
        let temp = b[y]
        while y > 0 && isOrderedBefore(temp, b[y - 1]) {
            b[y] = b[y - 1]
            y -= 1
        }
        b[y] = temp
    }
    return b
}

您需要做的就是改变

levelsReverseArr = levelsArr.reversed()

sortedLevelArr = insertionSort(levelArr) { $0.id < $1.id }