我有一个从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")]
答案 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 }