【问题标题】:RealmSwift: Count number of unique wordsRealmSwift:计算唯一单词的数量
【发布时间】:2020-05-30 23:20:39
【问题描述】:

鉴于以下设置:

class Message: Object {

    @objc dynamic var name: String = ""
    @objc dynamic var message: String = ""
}

class Chat: Object {

    var messages = List<Message>()
    var people = List<Person>()

    @objc dynamic var name:String = ""
    @objc dynamic var path:String = ""
}

有没有更有效的方法使用函数式编程来计算 Message 中的 message 变量中唯一词的数量?

let messages = Array(chat.messages)
let wordDictionary = [String:Int]()
let peopleDictionary = [String]()

for messageObject in messages {

   let words = messageObject.message.components(separatedBy: " ")
   for word in words {
      if wordDictionary[word] != nil {
          wordDictionary[word] += 1
      }else{
         wordDictionary[word] = 0
      }
   }
}

【问题讨论】:

    标签: swift realm nspredicate


    【解决方案1】:

    是的,您可以使用 enumerateSubstrings(in: Range) .byWords 将您的句子分解为单词并使用 reduce 方法计算其频率。不要忘记将单词小写以确保它们不会被视为不同的单词:


    extension StringProtocol {
        var byWords: [SubSequence] { components(separated: .byWords) }
        func components(separated options: String.EnumerationOptions)-> [SubSequence] {
            var components: [SubSequence] = []
            enumerateSubstrings(in: startIndex..., options: options) { _, range, _, _ in components.append(self[range]) }
            return components
        }
    }
    

    extension Sequence where Element: Hashable {
        var frequency: [Element: Int] { reduce(into: [:]) { $0[$1, default: 0] += 1 } }
    }
    

    用法:

    let sentence1 = "Given the following setup:"
    let sentence2 = "Is there a more efficient way using functional programming to calculate the number of unique words within the message variable within Message"
    
    let sentences = [sentence1, sentence2]
    let frequency = sentences
        .joined(separator: "\n")
        .lowercased()
        .byWords
        .frequency
    
    print(frequency.sorted(by: {$0.value > $1.value }))
    

    这将打印出来

    [(key: "the", value: 3), (key: "within", value: 2), (key: "message", value: 2), (key: "following", value: 1), (key: "way", value: 1), (key: "more", value: 1), (key: "to", value: 1), (key: "calculate", value: 1), (key: "number", value: 1), (key: "there", value: 1), (key: "a", value: 1), (key: "is", value: 1), (key: "unique", value: 1), (key: "setup", value: 1), (key: "using", value: 1), (key: "programming", 值:1),(键:“给定”,值:1),(键:“单词”,值:1),(键: “变量”,值:1),(键:“功能”,值:1),(键: “高效”,值:1),(键:“的”,值:1)]

    【讨论】:

      【解决方案2】:

      您要求进行函数式编程并且您正在使用 .componentsSeparatedBy(" ") 所以假设所有单词之间都有空格。

      让我们使用 .map、.flatmap 和 Set 的强大功能,它们保证是唯一的元素。例如:

      let sentence = "Every good boy does fine does" //6 total words, 5 unique
      let words = sentence.components(separatedBy: " ")
      let wordSet = Set(words)
      print(wordSet.count)
      

      输出是

      5
      

      然后将其应用于问题:

      let messages = Array(chat.messages) //makes the Realm list a Swift Array
      let x = messages.map { msgString -> [String] in
          let y = msgString.message.components(separatedBy: " ")
          return y
      }
      let uniqueWords = Set( x.flatMap { $0 } )
      print(uniqueWords.count)
      

      map 函数将获取消息数组中的每条消息,并将其分解为数组字符串数组,如下所示

      [ [word0, word1, word2], [word3, word4, word5] ]
      

      然后 flatMap 将数组数组映射为单个单词数组

      Finally Set 获取所有单词并创建一组唯一单词。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-02
        相关资源
        最近更新 更多