快速分离句子和问题的功能

时间:2022-02-08 02:44:43

I want the function below to separate the sentences into an array and the questions into an array and inserting "," where the "." and "?" belong. At the moment it's printing both in the same array. Any ideas on how to fix this?

我希望下面的函数将句子分成数组,将问题分成数组并插入“,”,其中“。”和“?”属于。目前它在同一阵列中打印。有想法该怎么解决这个吗?

func separateAllSentences() {

    // needs to print just the sentences
    func separateDeclarations() { // AKA Separate sentences that end in "."
        if userInput.range(of: ".") != nil { // Notice how lowercased() wasn't used
            numSentencesBefore = userInput.components(separatedBy: ".") // Hasn't subtracted 1 yet
            numSentencesAfter = numSentencesBefore.count - 1
            separateSentencesArray = Array(numSentencesBefore)
            print("# Of Sentences = \(numSentencesAfter)")
            print(separateSentencesArray)
        } else {
            print("There are no declarations found.")
        }
    }

    // needs to print just the questions
    func separateQuestions() { // Pretty Self Explanitory
        if userInput.range(of: "?") != nil {
            numQuestionsBefore = userInput.components(separatedBy: "?")
            numQuestionsAfter = numQuestionsBefore.count - 1
            separateQuestionsArray = Array(numQuestionsBefore)
            print("# Of Questions = \(numQuestionsAfter)")
            print(separateQuestionsArray)
        } else {
            print("There are no questions found. I have nothing to solve. Please rephrase the work to solve as a question.")
        }
    }

    // TODO: - Separate Commas
    func separateCommas() {

    }

    separateDeclarations()
    separateQuestions()
}

Console Prints Out:

控制台打印出来:

Ned rode his bike 7 miles to the library. He took a shortcut on the way home which was only 5 miles long. How many miles did Ned ride altogether?

内德骑自行车7英里到图书馆。他在回家的路上走了一条捷径,只有5英里长。 Ned骑了多少英里?

[# Of Sentences = 2]

[句子数= 2]

["Ned rode his bike 7 miles to the library", "\nHe took a shortcut on the way home which was only 5 miles long", "\nHow many miles did Ned ride altogether?\n"]

[“Ned骑着他的自行车7英里到了图书馆”,“\ n他在回家的路上走了一条捷径,只有5英里长”,“\ n Ned骑了多少英里?”n“

[# Of Questions = 1]

[问题数量= 1]

["Ned rode his bike 7 miles to the library.\nHe took a shortcut on the way home which was only 5 miles long.\nHow many miles did Ned ride altogether", "\n"]

[“Ned骑着他的自行车7英里到了图书馆。\ n他在回家的路上走了一条捷径,只有5英里长。\ n Ned骑了多少英里”,“\ n”]

Ned rode his bike 7 miles to the library. He took a shortcut on the way home which was only 5 miles long. How many miles did Ned ride altogether?

内德骑自行车7英里到图书馆。他在回家的路上走了一条捷径,只有5英里长。 Ned骑了多少英里?

It Should Print Out

它应该打印出来

[# Of Sentences = 2]

[句子数= 2]

[# Of Questions = 1]

[问题数量= 1]

Sentences: ["Ned rode his bike 7 miles to the library. He took a shortcut on the way home which was only 5 miles long."]

句子:[“Ned骑自行车7英里到了图书馆。他在回家的路上走了一条捷径,只有5英里长。”]

Questions: ["How many miles did Ned ride altogether?"]

问题:[“Ned骑了多少英里?”]

3 个解决方案

#1


1  

I would suggest not separating based upon the presence of a character, but rather enumate using the .bySentences option (which can more gracefully handle punctuation which is not terminating a sentence). Then iterate once through your string, appending to the appropriate array, e.g. in Swift 3:

我建议不要根据角色的存在进行分离,而是使用.bySentences选项进行分离(可以更优雅地处理未终止句子的标点符号)。然后在您的字符串中迭代一次,附加到相应的数组,例如在Swift 3中:

var questions  = [String]()
var statements = [String]()
var unknown    = [String]()

let string = "Ned deployed version 1.0 of his app. He wrote very elegant code. How much money did Ned make?"

string.enumerateSubstrings(in: string.startIndex ..< string.endIndex, options: .bySentences) { string, _, _, _ in
    if let sentence = string?.trimmingCharacters(in: .whitespacesAndNewlines), let lastCharacter = sentence.characters.last {
        switch lastCharacter {
        case ".":
            statements.append(sentence)
        case "?":
            questions.append(sentence)
        default:
            unknown.append(sentence)
        }
    }
}

print("questions:  \(questions)")
print("statements: \(statements)")
print("unknown:    \(unknown)")

#2


2  

This snippet could use some refactoring to replace the common code but it works as is.

此代码段可以使用一些重构来替换公共代码,但它可以按原样运行。

let punctuation = CharacterSet(charactersIn: ".?")
let sentences = userInput.components(separatedBy: punctuation)

let questions = sentences.filter {
  guard let range = userInput.range(of: $0) else { return false }
  let start = range.upperBound
  let end   = userInput.index(after: start)
  let punctuation = userInput.substring(with: Range(uncheckedBounds: (start, end)))
  return punctuation == "?"
}
let statements = sentences.filter {
  guard let range = userInput.range(of: $0) else { return false }
  let start = range.upperBound
  let end   = userInput.index(after: start)
  let punctuation = userInput.substring(with: Range(uncheckedBounds: (start, end)))
  return punctuation == "."
}

Looking at the closure first, the range variable contains the indices of the sentence in the user input. We want to get the punctuation trailing that particular sentence so we start with its upper bound and find the next index past it. Using substring, we extract the punctuation and compare it to either . or ?.

首先查看闭包,range变量包含用户输入中句子的索引。我们希望得到跟踪该特定句子的标点符号,因此我们从其上限开始并找到超过它的下一个索引。使用子字符串,我们提取标点符号并将其与之比较。要么 ?。

Now that we have code that will return true or false whether we have a question or statement sentence, we use filter to iterate over the array of all sentences and return only an array of questions or statements.

既然我们有代码将返回true或false,无论我们是否有问题或语句,我们使用filter迭代所有句子的数组并返回一组问题或语句。

#3


-1  

i make a simplest solution 快速分离句子和问题的功能

我做了一个最简单的解决方案

func separateDeclarations(userInput: String) { // AKA Separate sentences that end in "."
let array = userInput.components(separatedBy: ".")
let arrayQ = userInput.components(separatedBy: "?")

arrayQ.map { (string) -> String in
    if let question = string.components(separatedBy: ".").last {
        return question
    } else {
        return ""
    }
}

array.map { (string) -> String in
    if let question = string.components(separatedBy: "?").last {
        return question
    } else {
        return ""
    }
} 
}

#1


1  

I would suggest not separating based upon the presence of a character, but rather enumate using the .bySentences option (which can more gracefully handle punctuation which is not terminating a sentence). Then iterate once through your string, appending to the appropriate array, e.g. in Swift 3:

我建议不要根据角色的存在进行分离,而是使用.bySentences选项进行分离(可以更优雅地处理未终止句子的标点符号)。然后在您的字符串中迭代一次,附加到相应的数组,例如在Swift 3中:

var questions  = [String]()
var statements = [String]()
var unknown    = [String]()

let string = "Ned deployed version 1.0 of his app. He wrote very elegant code. How much money did Ned make?"

string.enumerateSubstrings(in: string.startIndex ..< string.endIndex, options: .bySentences) { string, _, _, _ in
    if let sentence = string?.trimmingCharacters(in: .whitespacesAndNewlines), let lastCharacter = sentence.characters.last {
        switch lastCharacter {
        case ".":
            statements.append(sentence)
        case "?":
            questions.append(sentence)
        default:
            unknown.append(sentence)
        }
    }
}

print("questions:  \(questions)")
print("statements: \(statements)")
print("unknown:    \(unknown)")

#2


2  

This snippet could use some refactoring to replace the common code but it works as is.

此代码段可以使用一些重构来替换公共代码,但它可以按原样运行。

let punctuation = CharacterSet(charactersIn: ".?")
let sentences = userInput.components(separatedBy: punctuation)

let questions = sentences.filter {
  guard let range = userInput.range(of: $0) else { return false }
  let start = range.upperBound
  let end   = userInput.index(after: start)
  let punctuation = userInput.substring(with: Range(uncheckedBounds: (start, end)))
  return punctuation == "?"
}
let statements = sentences.filter {
  guard let range = userInput.range(of: $0) else { return false }
  let start = range.upperBound
  let end   = userInput.index(after: start)
  let punctuation = userInput.substring(with: Range(uncheckedBounds: (start, end)))
  return punctuation == "."
}

Looking at the closure first, the range variable contains the indices of the sentence in the user input. We want to get the punctuation trailing that particular sentence so we start with its upper bound and find the next index past it. Using substring, we extract the punctuation and compare it to either . or ?.

首先查看闭包,range变量包含用户输入中句子的索引。我们希望得到跟踪该特定句子的标点符号,因此我们从其上限开始并找到超过它的下一个索引。使用子字符串,我们提取标点符号并将其与之比较。要么 ?。

Now that we have code that will return true or false whether we have a question or statement sentence, we use filter to iterate over the array of all sentences and return only an array of questions or statements.

既然我们有代码将返回true或false,无论我们是否有问题或语句,我们使用filter迭代所有句子的数组并返回一组问题或语句。

#3


-1  

i make a simplest solution 快速分离句子和问题的功能

我做了一个最简单的解决方案

func separateDeclarations(userInput: String) { // AKA Separate sentences that end in "."
let array = userInput.components(separatedBy: ".")
let arrayQ = userInput.components(separatedBy: "?")

arrayQ.map { (string) -> String in
    if let question = string.components(separatedBy: ".").last {
        return question
    } else {
        return ""
    }
}

array.map { (string) -> String in
    if let question = string.components(separatedBy: "?").last {
        return question
    } else {
        return ""
    }
} 
}