快速(性能)搜索数组元素的最佳方法

时间:2018-08-05 16:12:30

标签: arrays swift search

我正在制作一个应用程序,需要从可以随时更改的数组中获取数据。

例如数组:

posts_data: {
  ["id": 1, "text": "Hello"],
  ["id": 4, "text": "Good morning"],
  ["id": 6, "text": "Test"]
}

假设我需要更改post 1的文本,但是我不知道它的索引。然后过一会儿,我需要再次更改它,但帖子可能会处于其他位置。

  

func doSomeThing():

if let index = posts_data.index(where: { $0.id == 1 }) {
    posts_data[index].text = "NEW TEXT"

    dispatchQueue.global().async {
    // Do something async, then I need to change the text again
    // But I need to search for the index again
    // Because the data source might changed meanwhile

        if let index2 = posts_data.index(where: { $0.id == 1 }) {
            posts_data[index2].text = "AGAIN"
            posts_data[index2].text = "AND AGAIN"
        }
    }

}

有点复杂。我想到了以下想法:将搜索放入自定义类中,如果ID被找到,则返回该帖子:

class MainViewController : UIViewController {
    ...


    func doSomeThing(){
        if PostsClass.shared.getPost(id: 1) == nil {
           return // Just in case if not found
        }

        PostsClass.shared.getPost(id: 1).text = "NEW TEXT"
        dispatchQueue.global().async {
            // Bla bla

            PostsClass.shared.getPost(id: 1).text = "AGAIN"
            PostsClass.shared.getPost(id: 1).text = "AND AGAIN"

        }
    }
}


class PostsClass {
    static let shared = PostsClass()
    func getPost(id: Int) -> Post? {
        if let index = posts_data.index(where: { $0.id == id }) {
            return posts_data[index]
        }
        return nil
    }
}

这好还是一个坏主意?还是有比这更简单的方法?

3 个答案:

答案 0 :(得分:1)

基本上,如果尝试在数组中搜索是正确的。 但是,您可以使用其他方法直接返回帖子:

return posts_data.first { $0.id == id }

答案 1 :(得分:1)

first

是一种更有效的方法
class PostsClass {
    static let shared = PostsClass()
    func getPost(id: Int) -> Post? {
        return posts_data.first{ $0.id == id }
    }
}

请,这是Swift,将数组命名为postsData或简单地命名为posts

答案 2 :(得分:0)

认为您可能正在寻找这样的东西:

var posts_data: [[String: Any]]  = [
    ["id": 1, "text": "Hello"],
    ["id": 4, "text": "Good morning"],
    ["id": 6, "text": "Test"]
]

var filtered_posts_data: [[String: Any]]   = []

override func viewDidLoad() {

    filtered_posts_data = posts_data.filter({$0.contains(where: { (arg) -> Bool in
        if let valueString = arg.value as? String{
            return valueString.range(of: "hello", options: .caseInsensitive) != nil
        }else{
            return false
        }
    })})

    print(filtered_posts_data) //[["id": 1, "text": "Hello"]]
}