2017-02-19 9 views
-1

У меня есть функция, которая извлекает данные из 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")] 

При печати снимка хорошо упорядоченную, но когда я принести де данные и поместить каждый уровень в массив больше не упорядочен.

Почему это так и как я могу упорядочить мои данные, как в моментальном снимке?

спасибо.


UPDATE

со следующими изменениями:

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

Я не совсем уверен, почему Firebase любит 'возиться' с массивом, поэтому я не могу ответить на эту сторону вашего вопроса, но чтобы решить проблему, вы можете использовать .queryOrdered(byChild:) заказать снимки, изменяя «идентификатор» к чему-либо, что может приказать ваши объекты:

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

Вам также может понадобиться, чтобы полностью изменить массив, когда он будет полностью или обновляется ...

UPDATE:

Это мы надеемся, должны «своего рода» ваш вопрос, если вы получаете мой каламбур, то есть, если уровень идентификатор является ИНТ, и вы хотите, чтобы заказать для лвл 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 } 
+0

Я редактировал вопрос с результатом изменений. Кажется, не работает, или я сделал ошибку? –

+0

Кажется, что это должно сработать, я использовал этот код только сегодня утром, попробуйте изменить вход byChild на один из других в базе данных, чтобы проверить, я обычно использую timetstamp и что работает 10/10 –

+0

Не работает для другие входы базы данных :( –

 Смежные вопросы

  • Нет связанных вопросов^_^