如何将“String.Element”转换为“Int”?

Posted

技术标签:

【中文标题】如何将“String.Element”转换为“Int”?【英文标题】:How to convert 'String.Element' to 'Int'? 【发布时间】:2021-10-11 08:35:39 【问题描述】:
var numsInStr = "1abc2x30yz67"
var sum = 0
for i in numsInStr 
    if i.isNumber == true 
       sum += i
    

print(sum)
问题在于如果声明对数字求和。它返回 - “无法将 'String.Element' (又名 'Character')类型的值转换为预期的参数类型 'Int'” 可以像我一样解决这个问题。我看到了一些答案,但答案非常简短且存在误解

输入:1abc2x30yz67 输出:100

【问题讨论】:

请注意:您的任务似乎是:迭代一个随机字符串,并将其中的所有数字相加。编程要求对所有细节都非常精确! 如果你的代码有效,目前,输出应该是6,你正在计算数字的出现次数,因为你正在做“+i”。您没有将其转换为数字。此外,由于您正在逐个字符地进行迭代,否则即使转换为整数,那么您的逻辑是1 + 2 + 3 + 0 + 6 + 7,而不是1 + 2 + 30 + 67。所以你的逻辑似乎有缺陷......你可能想寻找***.com/questions/30342744/… 关于这个错误检查这个:***.com/a/57156631/14733292这将帮助你"1abc2x30yz67".components(separatedBy: CharacterSet.decimalDigits.inverted).compactMap(Int($0)).reduce(0, +) @RajaKishan 是的,我之前看到过这段代码,但这段代码对初学者有误解。是否可以通过循环或其他方式解决此问题? 是的,使用 while 循环和潮汐另一个 var 来跟踪 nambar。只需迭代每个字符并找出直到后面的数字 【参考方案1】:

您的解决方案不起作用,因为您正在添加字符类型以集成类型值,首先您需要将字符对象转换为字符串,然后转换为整数以求和。 希望对你有帮助 谢谢?

    var numsInStr = "1abc2x30yz67"
    var sum = 0

    for i in numsInStr 
    
        if i.isNumber == true 
        
            sum = sum + Int(String(i))
        
   

   print(sum)

对于字符串中所有数字的总和,以下是最佳解决方案,您将根据问题的要求获得 100 的总和。

let numsInStr = "1abc2x30yz67"
    .components(separatedBy: .letters)
    .compactMap(Int.init)
    .reduce(0, +)
print(numsInStr)

【讨论】:

不应该产生1 + 2 + 3 + 0 + 6 + 7而不是1 + 2 + 30 + 67,输出19而不是100 您不应该强制解开错误Int init 的返回值,您应该选择绑定该值。 @Larme 不,我只是将其转换为整数并求和,让我考虑一下 @DávidPásztor 让你先生 由于您的两个代码不等效,因此具有误导性。您可能想明确告诉他们不是。您在第一部分解释了为什么它没有编译,并为目标问题提供了更高级别的解决方案。两种不同的“修复”。【参考方案2】:

sum += i 有什么问题,正如错误所说,iCharactersumInt。 你能在香蕉和苹果之间加法吗?这里的逻辑是一样的。 因此,您可能希望将其 Int 等同于 Int(i)

它返回一个可选值,因为不能保证i 是有效的。您事先检查isNumber,但线路本身并不知道这一点。所以你可以软解包,或者如果你确定强制解包:

sum += Int(String(i))! //Char -> String -> Int

因为有String.init(someChar)Int.init(someString),但没有Int.init(someChar),这就是为什么有双init()

但是,保持你的逻辑,你正在迭代每个字符的字符...... 所以,最后你有:

1 + 2 + 3 + 0 + 6 + 7(即19),而不是预期的1 + 2 + 30 + 67(即100)。

所以如果你想迭代,你需要将连续的数字“分组”...

使用基本的 for 循环,您可以做到这一点(这是一种可能的解决方案,可能不是更好的解决方案,而是一个可行的解决方案)

let numsInStr = "1abc2x30yz67"

var lastWasNumber = false
var intStrings: [String] = []

for aCharacter in numsInStr 
    if aCharacter.isNumber 
        if !lastWasNumber 
            intStrings.append(String(aCharacter))
         else 
            intStrings[intStrings.count - 1] = intStrings[intStrings.count - 1] + String(aCharacter)
        
        lastWasNumber = true
     else 
        lastWasNumber = false
    
    print("After processing: \(aCharacter) - got: \(intStrings)")


print(intStrings)

var sum = 0
for anIntString in intStrings 
    sum += Int(anIntString)!

print("Sum: \(sum)")

在你的水平上,毫不犹豫地添加print()(但不仅仅是变量,总是添加一个额外的文本,这将是从哪里知道它被调用的上下文)。

输出是:

$>After processing: 1 - got: ["1"]
$>After processing: a - got: ["1"]
$>After processing: b - got: ["1"]
$>After processing: c - got: ["1"]
$>After processing: 2 - got: ["1", "2"]
$>After processing: x - got: ["1", "2"]
$>After processing: 3 - got: ["1", "2", "3"]
$>After processing: 0 - got: ["1", "2", "30"]
$>After processing: y - got: ["1", "2", "30"]
$>After processing: z - got: ["1", "2", "30"]
$>After processing: 6 - got: ["1", "2", "30", "6"]
$>After processing: 7 - got: ["1", "2", "30", "67"]
$>["1", "2", "30", "67"]
$>100

我们依赖Int(someString)(并强制展开),但sum += Int(anIntString) ?? 0 应该更安全。因为对于太大的值,例如,如果您有“a1234567890123456789123456789123456789”,我不确定Int 是否足以处理该值。您需要注意一些边缘情况。

使用高级方法,您可以使用componentsSeparated(by:) 获取仅包含字符串和仅字母的数组。然后,您可以filter()(如果需要),或compactMap(),如果可能,转换为Int,然后求和(使用reduce(into:_:)

按照建议,另一种不保留String 列表的解决方案可能是:

var sum = 0
var lastWasNumber = false
var currentIntString = ""

for aCharacter in numsInStr 
    if aCharacter.isNumber 
        if !lastWasNumber 
            sum += Int(currentIntString) ?? 0
            currentIntString = "" // Reset, but in fact since we override with the next line, it's not necessary to write it
            currentIntString = String(aCharacter)
         else 
            currentIntString += String(aCharacter)
        
        lastWasNumber = true
     else 
        lastWasNumber = false
    
    print("After processing: \(aCharacter) - got: \(currentIntString) - current sum: \(sum)")


sum += Int(currentIntString) ?? 0

print("Sum: \(sum)")

在这里,我们将currentInString 保留为“缓冲区”。

这也可以通过删除 lastWasNumber 并改为检查 currentIntString 来简化:

var sum = 0
var currentIntString = ""

for aCharacter in numsInStr 
    if aCharacter.isNumber 
        if currentIntString.isEmpty 
            currentIntString = String(aCharacter)
         else 
            currentIntString += String(aCharacter)
        
     else 
        sum += Int(currentIntString) ?? 0
        currentIntString = ""
    
    print("After processing: \(aCharacter) - got: \(currentIntString) - current sum: \(sum)")


sum += Int(currentIntString) ?? 0

print("Sum: \(sum)")

【讨论】:

您可以直接计算总和,而无需将其存储在数组中,也无需对总和数组进行额外循环。它将降低时间和空间复杂度。但也许是为了解释? 确实如此。代替[String],我们可以使用String 来保存当前字符串(例如,如果我们想在示例中添加“7”或“67”)。在“else”中,我们可以添加它,并“重置”该字符串,并将其添加到循环末尾以防万一。但我认为根据用户级别可能太复杂了。

以上是关于如何将“String.Element”转换为“Int”?的主要内容,如果未能解决你的问题,请参考以下文章

Oracle如何将字符串转换为IN后的选项

如何将 MySQL“NOT IN”数组转换为整数

如何快速将返回的 Python-in-Lua numpy 数组转换为 Lua Torch 张量?

如何将此项目转换为代码?

使用 pivot 和 in 子句将行转换为列

将 SQL 子查询转换为包含 IN、DISTINCT 关键字的 LINQ 格式