Levenshtein distance in Swift3












1















I'm using a tutorial from Rosetta Code to calculate Levenshtein distance. It seems their code is in Swift2 so I get this error Binary operator '+' cannot be applied to operands of type '[Int]' and 'Repeated<String.CharacterView>' when doing this: var cur = [i + 2] + empty where let empty = repeatElement(s, count: 0). How can I go about this?










share|improve this question


















  • 1





    Not a direct answer to your question, but here stackoverflow.com/questions/26990394/… is an implementation which should require only minor modifications for Swift 3.

    – Martin R
    May 21 '17 at 22:06











  • Thanks, worked but would still love to use their(Rosetta) method since it seems shorter.

    – styl3r
    May 21 '17 at 22:25
















1















I'm using a tutorial from Rosetta Code to calculate Levenshtein distance. It seems their code is in Swift2 so I get this error Binary operator '+' cannot be applied to operands of type '[Int]' and 'Repeated<String.CharacterView>' when doing this: var cur = [i + 2] + empty where let empty = repeatElement(s, count: 0). How can I go about this?










share|improve this question


















  • 1





    Not a direct answer to your question, but here stackoverflow.com/questions/26990394/… is an implementation which should require only minor modifications for Swift 3.

    – Martin R
    May 21 '17 at 22:06











  • Thanks, worked but would still love to use their(Rosetta) method since it seems shorter.

    – styl3r
    May 21 '17 at 22:25














1












1








1








I'm using a tutorial from Rosetta Code to calculate Levenshtein distance. It seems their code is in Swift2 so I get this error Binary operator '+' cannot be applied to operands of type '[Int]' and 'Repeated<String.CharacterView>' when doing this: var cur = [i + 2] + empty where let empty = repeatElement(s, count: 0). How can I go about this?










share|improve this question














I'm using a tutorial from Rosetta Code to calculate Levenshtein distance. It seems their code is in Swift2 so I get this error Binary operator '+' cannot be applied to operands of type '[Int]' and 'Repeated<String.CharacterView>' when doing this: var cur = [i + 2] + empty where let empty = repeatElement(s, count: 0). How can I go about this?







swift swift3 levenshtein-distance rosetta-code






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked May 21 '17 at 21:58









styl3rstyl3r

417619




417619








  • 1





    Not a direct answer to your question, but here stackoverflow.com/questions/26990394/… is an implementation which should require only minor modifications for Swift 3.

    – Martin R
    May 21 '17 at 22:06











  • Thanks, worked but would still love to use their(Rosetta) method since it seems shorter.

    – styl3r
    May 21 '17 at 22:25














  • 1





    Not a direct answer to your question, but here stackoverflow.com/questions/26990394/… is an implementation which should require only minor modifications for Swift 3.

    – Martin R
    May 21 '17 at 22:06











  • Thanks, worked but would still love to use their(Rosetta) method since it seems shorter.

    – styl3r
    May 21 '17 at 22:25








1




1





Not a direct answer to your question, but here stackoverflow.com/questions/26990394/… is an implementation which should require only minor modifications for Swift 3.

– Martin R
May 21 '17 at 22:06





Not a direct answer to your question, but here stackoverflow.com/questions/26990394/… is an implementation which should require only minor modifications for Swift 3.

– Martin R
May 21 '17 at 22:06













Thanks, worked but would still love to use their(Rosetta) method since it seems shorter.

– styl3r
May 21 '17 at 22:25





Thanks, worked but would still love to use their(Rosetta) method since it seems shorter.

– styl3r
May 21 '17 at 22:25












3 Answers
3






active

oldest

votes


















5














There were a couple of changes to make.




  • The construction of the Array empty.

  • enumerate() is now enumerated()

  • successor() doesn't exist anymore so I replaced it with +1


So the function is now



Swift 4:



func levDis(_ w1: String, _ w2: String) -> Int {
let empty = [Int](repeating:0, count: w2.count)
var last = [Int](0...w2.count)

for (i, char1) in w1.enumerated() {
var cur = [i + 1] + empty
for (j, char2) in w2.enumerated() {
cur[j + 1] = char1 == char2 ? last[j] : min(last[j], last[j + 1], cur[j]) + 1
}
last = cur
}
return last.last!
}


Swift 3:



func levDis(w1: String, w2: String) -> Int {

let (t, s) = (w1.characters, w2.characters)

let empty = Array<Int>(repeating:0, count: s.count)
var last = [Int](0...s.count)

for (i, tLett) in t.enumerated() {
var cur = [i + 1] + empty
for (j, sLett) in s.enumerated() {
cur[j + 1] = tLett == sLett ? last[j] : min(last[j], last[j + 1], cur[j])+1
}
last = cur
}
return last.last!
}





share|improve this answer

































    1














    Updated and improved answer to Swift 4, based on @Spads answer.



    extension String {
    func levenshteinDistanceScore(to string: String, ignoreCase: Bool = true, trimWhiteSpacesAndNewLines: Bool = true) -> Float {

    var firstString = self
    var secondString = string

    if ignoreCase {
    firstString = firstString.lowercased()
    secondString = secondString.lowercased()
    }
    if trimWhiteSpacesAndNewLines {
    firstString = firstString.trimmingCharacters(in: .whitespacesAndNewlines)
    secondString = secondString.trimmingCharacters(in: .whitespacesAndNewlines)
    }

    let empty = [Int](repeating:0, count: secondString.count)
    var last = [Int](0...secondString.count)

    for (i, tLett) in firstString.enumerated() {
    var cur = [i + 1] + empty
    for (j, sLett) in secondString.enumerated() {
    cur[j + 1] = tLett == sLett ? last[j] : Swift.min(last[j], last[j + 1], cur[j])+1
    }
    last = cur
    }

    // maximum string length between the two
    let lowestScore = max(firstString.count, secondString.count)

    if let validDistance = last.last {
    return 1 - (Float(validDistance) / Float(lowestScore))
    }

    return 0.0
    }
    }

    infix operator =~
    func =~(string: String, otherString: String) -> Bool {
    return string.levenshteinDistanceScore(to: otherString) >= 0.85
    }





    share|improve this answer


























    • What does this actually calculate? As far as I know the Levenshtein Distance is an Int, not a float.

      – hashier
      Dec 2 '18 at 8:20



















    0














    func ~=(string: String, otherString: String) -> Bool {
    return string.levenshteinDistanceScore(to: otherString) >= 0.85
    }





    share|improve this answer


























    • This is the correct operator Overloading for levenshteinDistanceScore String Extension. stackoverflow.com/a/48976605/9991497

      – akash soni
      Nov 16 '18 at 8:13











    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f44102213%2flevenshtein-distance-in-swift3%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    5














    There were a couple of changes to make.




    • The construction of the Array empty.

    • enumerate() is now enumerated()

    • successor() doesn't exist anymore so I replaced it with +1


    So the function is now



    Swift 4:



    func levDis(_ w1: String, _ w2: String) -> Int {
    let empty = [Int](repeating:0, count: w2.count)
    var last = [Int](0...w2.count)

    for (i, char1) in w1.enumerated() {
    var cur = [i + 1] + empty
    for (j, char2) in w2.enumerated() {
    cur[j + 1] = char1 == char2 ? last[j] : min(last[j], last[j + 1], cur[j]) + 1
    }
    last = cur
    }
    return last.last!
    }


    Swift 3:



    func levDis(w1: String, w2: String) -> Int {

    let (t, s) = (w1.characters, w2.characters)

    let empty = Array<Int>(repeating:0, count: s.count)
    var last = [Int](0...s.count)

    for (i, tLett) in t.enumerated() {
    var cur = [i + 1] + empty
    for (j, sLett) in s.enumerated() {
    cur[j + 1] = tLett == sLett ? last[j] : min(last[j], last[j + 1], cur[j])+1
    }
    last = cur
    }
    return last.last!
    }





    share|improve this answer






























      5














      There were a couple of changes to make.




      • The construction of the Array empty.

      • enumerate() is now enumerated()

      • successor() doesn't exist anymore so I replaced it with +1


      So the function is now



      Swift 4:



      func levDis(_ w1: String, _ w2: String) -> Int {
      let empty = [Int](repeating:0, count: w2.count)
      var last = [Int](0...w2.count)

      for (i, char1) in w1.enumerated() {
      var cur = [i + 1] + empty
      for (j, char2) in w2.enumerated() {
      cur[j + 1] = char1 == char2 ? last[j] : min(last[j], last[j + 1], cur[j]) + 1
      }
      last = cur
      }
      return last.last!
      }


      Swift 3:



      func levDis(w1: String, w2: String) -> Int {

      let (t, s) = (w1.characters, w2.characters)

      let empty = Array<Int>(repeating:0, count: s.count)
      var last = [Int](0...s.count)

      for (i, tLett) in t.enumerated() {
      var cur = [i + 1] + empty
      for (j, sLett) in s.enumerated() {
      cur[j + 1] = tLett == sLett ? last[j] : min(last[j], last[j + 1], cur[j])+1
      }
      last = cur
      }
      return last.last!
      }





      share|improve this answer




























        5












        5








        5







        There were a couple of changes to make.




        • The construction of the Array empty.

        • enumerate() is now enumerated()

        • successor() doesn't exist anymore so I replaced it with +1


        So the function is now



        Swift 4:



        func levDis(_ w1: String, _ w2: String) -> Int {
        let empty = [Int](repeating:0, count: w2.count)
        var last = [Int](0...w2.count)

        for (i, char1) in w1.enumerated() {
        var cur = [i + 1] + empty
        for (j, char2) in w2.enumerated() {
        cur[j + 1] = char1 == char2 ? last[j] : min(last[j], last[j + 1], cur[j]) + 1
        }
        last = cur
        }
        return last.last!
        }


        Swift 3:



        func levDis(w1: String, w2: String) -> Int {

        let (t, s) = (w1.characters, w2.characters)

        let empty = Array<Int>(repeating:0, count: s.count)
        var last = [Int](0...s.count)

        for (i, tLett) in t.enumerated() {
        var cur = [i + 1] + empty
        for (j, sLett) in s.enumerated() {
        cur[j + 1] = tLett == sLett ? last[j] : min(last[j], last[j + 1], cur[j])+1
        }
        last = cur
        }
        return last.last!
        }





        share|improve this answer















        There were a couple of changes to make.




        • The construction of the Array empty.

        • enumerate() is now enumerated()

        • successor() doesn't exist anymore so I replaced it with +1


        So the function is now



        Swift 4:



        func levDis(_ w1: String, _ w2: String) -> Int {
        let empty = [Int](repeating:0, count: w2.count)
        var last = [Int](0...w2.count)

        for (i, char1) in w1.enumerated() {
        var cur = [i + 1] + empty
        for (j, char2) in w2.enumerated() {
        cur[j + 1] = char1 == char2 ? last[j] : min(last[j], last[j + 1], cur[j]) + 1
        }
        last = cur
        }
        return last.last!
        }


        Swift 3:



        func levDis(w1: String, w2: String) -> Int {

        let (t, s) = (w1.characters, w2.characters)

        let empty = Array<Int>(repeating:0, count: s.count)
        var last = [Int](0...s.count)

        for (i, tLett) in t.enumerated() {
        var cur = [i + 1] + empty
        for (j, sLett) in s.enumerated() {
        cur[j + 1] = tLett == sLett ? last[j] : min(last[j], last[j + 1], cur[j])+1
        }
        last = cur
        }
        return last.last!
        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Dec 2 '18 at 9:16









        hashier

        3,87612041




        3,87612041










        answered May 21 '17 at 22:28









        SpadsSpads

        1,6511520




        1,6511520

























            1














            Updated and improved answer to Swift 4, based on @Spads answer.



            extension String {
            func levenshteinDistanceScore(to string: String, ignoreCase: Bool = true, trimWhiteSpacesAndNewLines: Bool = true) -> Float {

            var firstString = self
            var secondString = string

            if ignoreCase {
            firstString = firstString.lowercased()
            secondString = secondString.lowercased()
            }
            if trimWhiteSpacesAndNewLines {
            firstString = firstString.trimmingCharacters(in: .whitespacesAndNewlines)
            secondString = secondString.trimmingCharacters(in: .whitespacesAndNewlines)
            }

            let empty = [Int](repeating:0, count: secondString.count)
            var last = [Int](0...secondString.count)

            for (i, tLett) in firstString.enumerated() {
            var cur = [i + 1] + empty
            for (j, sLett) in secondString.enumerated() {
            cur[j + 1] = tLett == sLett ? last[j] : Swift.min(last[j], last[j + 1], cur[j])+1
            }
            last = cur
            }

            // maximum string length between the two
            let lowestScore = max(firstString.count, secondString.count)

            if let validDistance = last.last {
            return 1 - (Float(validDistance) / Float(lowestScore))
            }

            return 0.0
            }
            }

            infix operator =~
            func =~(string: String, otherString: String) -> Bool {
            return string.levenshteinDistanceScore(to: otherString) >= 0.85
            }





            share|improve this answer


























            • What does this actually calculate? As far as I know the Levenshtein Distance is an Int, not a float.

              – hashier
              Dec 2 '18 at 8:20
















            1














            Updated and improved answer to Swift 4, based on @Spads answer.



            extension String {
            func levenshteinDistanceScore(to string: String, ignoreCase: Bool = true, trimWhiteSpacesAndNewLines: Bool = true) -> Float {

            var firstString = self
            var secondString = string

            if ignoreCase {
            firstString = firstString.lowercased()
            secondString = secondString.lowercased()
            }
            if trimWhiteSpacesAndNewLines {
            firstString = firstString.trimmingCharacters(in: .whitespacesAndNewlines)
            secondString = secondString.trimmingCharacters(in: .whitespacesAndNewlines)
            }

            let empty = [Int](repeating:0, count: secondString.count)
            var last = [Int](0...secondString.count)

            for (i, tLett) in firstString.enumerated() {
            var cur = [i + 1] + empty
            for (j, sLett) in secondString.enumerated() {
            cur[j + 1] = tLett == sLett ? last[j] : Swift.min(last[j], last[j + 1], cur[j])+1
            }
            last = cur
            }

            // maximum string length between the two
            let lowestScore = max(firstString.count, secondString.count)

            if let validDistance = last.last {
            return 1 - (Float(validDistance) / Float(lowestScore))
            }

            return 0.0
            }
            }

            infix operator =~
            func =~(string: String, otherString: String) -> Bool {
            return string.levenshteinDistanceScore(to: otherString) >= 0.85
            }





            share|improve this answer


























            • What does this actually calculate? As far as I know the Levenshtein Distance is an Int, not a float.

              – hashier
              Dec 2 '18 at 8:20














            1












            1








            1







            Updated and improved answer to Swift 4, based on @Spads answer.



            extension String {
            func levenshteinDistanceScore(to string: String, ignoreCase: Bool = true, trimWhiteSpacesAndNewLines: Bool = true) -> Float {

            var firstString = self
            var secondString = string

            if ignoreCase {
            firstString = firstString.lowercased()
            secondString = secondString.lowercased()
            }
            if trimWhiteSpacesAndNewLines {
            firstString = firstString.trimmingCharacters(in: .whitespacesAndNewlines)
            secondString = secondString.trimmingCharacters(in: .whitespacesAndNewlines)
            }

            let empty = [Int](repeating:0, count: secondString.count)
            var last = [Int](0...secondString.count)

            for (i, tLett) in firstString.enumerated() {
            var cur = [i + 1] + empty
            for (j, sLett) in secondString.enumerated() {
            cur[j + 1] = tLett == sLett ? last[j] : Swift.min(last[j], last[j + 1], cur[j])+1
            }
            last = cur
            }

            // maximum string length between the two
            let lowestScore = max(firstString.count, secondString.count)

            if let validDistance = last.last {
            return 1 - (Float(validDistance) / Float(lowestScore))
            }

            return 0.0
            }
            }

            infix operator =~
            func =~(string: String, otherString: String) -> Bool {
            return string.levenshteinDistanceScore(to: otherString) >= 0.85
            }





            share|improve this answer















            Updated and improved answer to Swift 4, based on @Spads answer.



            extension String {
            func levenshteinDistanceScore(to string: String, ignoreCase: Bool = true, trimWhiteSpacesAndNewLines: Bool = true) -> Float {

            var firstString = self
            var secondString = string

            if ignoreCase {
            firstString = firstString.lowercased()
            secondString = secondString.lowercased()
            }
            if trimWhiteSpacesAndNewLines {
            firstString = firstString.trimmingCharacters(in: .whitespacesAndNewlines)
            secondString = secondString.trimmingCharacters(in: .whitespacesAndNewlines)
            }

            let empty = [Int](repeating:0, count: secondString.count)
            var last = [Int](0...secondString.count)

            for (i, tLett) in firstString.enumerated() {
            var cur = [i + 1] + empty
            for (j, sLett) in secondString.enumerated() {
            cur[j + 1] = tLett == sLett ? last[j] : Swift.min(last[j], last[j + 1], cur[j])+1
            }
            last = cur
            }

            // maximum string length between the two
            let lowestScore = max(firstString.count, secondString.count)

            if let validDistance = last.last {
            return 1 - (Float(validDistance) / Float(lowestScore))
            }

            return 0.0
            }
            }

            infix operator =~
            func =~(string: String, otherString: String) -> Bool {
            return string.levenshteinDistanceScore(to: otherString) >= 0.85
            }






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jul 27 '18 at 10:58

























            answered Feb 25 '18 at 17:54









            Daniel IllescasDaniel Illescas

            1,999920




            1,999920













            • What does this actually calculate? As far as I know the Levenshtein Distance is an Int, not a float.

              – hashier
              Dec 2 '18 at 8:20



















            • What does this actually calculate? As far as I know the Levenshtein Distance is an Int, not a float.

              – hashier
              Dec 2 '18 at 8:20

















            What does this actually calculate? As far as I know the Levenshtein Distance is an Int, not a float.

            – hashier
            Dec 2 '18 at 8:20





            What does this actually calculate? As far as I know the Levenshtein Distance is an Int, not a float.

            – hashier
            Dec 2 '18 at 8:20











            0














            func ~=(string: String, otherString: String) -> Bool {
            return string.levenshteinDistanceScore(to: otherString) >= 0.85
            }





            share|improve this answer


























            • This is the correct operator Overloading for levenshteinDistanceScore String Extension. stackoverflow.com/a/48976605/9991497

              – akash soni
              Nov 16 '18 at 8:13
















            0














            func ~=(string: String, otherString: String) -> Bool {
            return string.levenshteinDistanceScore(to: otherString) >= 0.85
            }





            share|improve this answer


























            • This is the correct operator Overloading for levenshteinDistanceScore String Extension. stackoverflow.com/a/48976605/9991497

              – akash soni
              Nov 16 '18 at 8:13














            0












            0








            0







            func ~=(string: String, otherString: String) -> Bool {
            return string.levenshteinDistanceScore(to: otherString) >= 0.85
            }





            share|improve this answer















            func ~=(string: String, otherString: String) -> Bool {
            return string.levenshteinDistanceScore(to: otherString) >= 0.85
            }






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 16 '18 at 21:35









            Tiago Martins Peres

            2,23162036




            2,23162036










            answered Nov 16 '18 at 8:12









            akash soniakash soni

            13




            13













            • This is the correct operator Overloading for levenshteinDistanceScore String Extension. stackoverflow.com/a/48976605/9991497

              – akash soni
              Nov 16 '18 at 8:13



















            • This is the correct operator Overloading for levenshteinDistanceScore String Extension. stackoverflow.com/a/48976605/9991497

              – akash soni
              Nov 16 '18 at 8:13

















            This is the correct operator Overloading for levenshteinDistanceScore String Extension. stackoverflow.com/a/48976605/9991497

            – akash soni
            Nov 16 '18 at 8:13





            This is the correct operator Overloading for levenshteinDistanceScore String Extension. stackoverflow.com/a/48976605/9991497

            – akash soni
            Nov 16 '18 at 8:13


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f44102213%2flevenshtein-distance-in-swift3%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            List item for chat from Array inside array React Native

            Thiostrepton

            Caerphilly