Jaro similarity: Difference between revisions

Add C# implementation
m (→‎{{header|REXX}}: optimized the function, increased the number of decimal digits shown in the output.)
(Add C# implementation)
 
(38 intermediate revisions by 23 users not shown)
Line 1:
{{task}}
 
The Jaro distance is a measure of edit distance between two strings; its inverse, called the ''Jaro similarity'', is a measure of two strings' similarity: the higher the value, the more similar the strings are. The score is normalized such that   '''0'''   equates to no similarities and   '''1'''   is an exact match.
The Jaro distance is a measure of similarity between two strings.
 
The higher the Jaro distance for two strings is, the more similar the strings are.
 
The score is normalized such that   '''0'''   equates to no similarity and   '''1'''   is an exact match.
 
 
;;Definition
 
The Jaro distancesimilarity &nbsp; <math>d_j</math> &nbsp; of two given strings &nbsp; <math>s_1</math> &nbsp; and &nbsp; <math>s_2</math> &nbsp; is
 
: <math>d_j = \left\{
Line 24 ⟶ 20:
 
 
Two characters from &nbsp; <math>s_1</math> &nbsp; and &nbsp; <math>s_2</math> &nbsp; respectively, are considered ''matching'' only if they are the same and not farther apart than &nbsp; <math>\left\lfloor\frac{\max(|s_1|,|s_2|)}{2}\right\rfloor-1</math> characters.
 
Each character of &nbsp; <math>s_1</math> &nbsp; is compared with all its matching characters in &nbsp; <math>s_2</math>. Each difference in position is half a ''transposition''; that is, the number of transpositions is half the number of characters which are common to the two strings but occupy different positions in each one.
characters in &nbsp; <math>s_2</math>.
 
The number of matching (but different sequence order) characters
divided by 2 defines the number of ''transpositions''.
 
 
Line 50 ⟶ 42:
;Task
 
Implement the Jaro-distance algorithm and show the distancessimilarity scores for each of the following pairs:
 
* ("MARTHA", "MARHTA")
Line 60 ⟶ 52:
* [[wp:Jaro-Winkler_distance|Jaro–Winkler distance]] on Wikipedia.
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">F jaro(s, t)
V s_len = s.len
V t_len = t.len
 
I s_len == 0 & t_len == 0
R 1.0
 
V match_distance = (max(s_len, t_len) I/ 2) - 1
V s_matches = [0B] * s_len
V t_matches = [0B] * t_len
V matches = 0
V transpositions = 0
 
L(i) 0 .< s_len
V start = max(0, i - match_distance)
V end = min(i + match_distance + 1, t_len)
 
L(j) start .< end
I t_matches[j]
L.continue
I s[i] != t[j]
L.continue
s_matches[i] = 1B
t_matches[j] = 1B
matches++
L.break
 
I matches == 0
R 0.0
 
V k = 0
L(i) 0 .< s_len
I !s_matches[i]
L.continue
L !t_matches[k]
k++
I s[i] != t[k]
transpositions++
k++
 
R ((Float(matches) / s_len) +
(Float(matches) / t_len) +
((matches - transpositions / 2) / matches)) / 3
 
L(s, t) [(‘MARTHA’, ‘MARHTA’),
(‘DIXON’, ‘DICKSONX’),
(‘JELLYFISH’, ‘SMELLYFISH’)]
print(‘jaro('#.', '#.') = #.10’.format(s, t, jaro(s, t)))</syntaxhighlight>
 
{{out}}
<pre>
jaro('MARTHA', 'MARHTA') = 0.9444444444
jaro('DIXON', 'DICKSONX') = 0.7666666667
jaro('JELLYFISH', 'SMELLYFISH') = 0.8962962963
</pre>
 
=={{header|Action!}}==
<langsyntaxhighlight lang="action">
DEFINE STRING="CHAR ARRAY" ; sys.act
DEFINE ASCII_SpaceBar="32"
Line 93 ⟶ 144:
IF Max<(I-L) THEN Max=I-L FI
Min=S2
IF Min>(I+L-1) THEN Min=I+L-1 FI
FOR K=Max TO Min DO
IF str1(I)=str2(K) THEN
Line 132 ⟶ 183:
PUTE()
 
SCopy(Word_1,"MARTHALIGITA") SCopy(Word_2,"MARHTALIGA")
PrintF("%S - %S%E",Word_1,Word_2)
result=JaroDistance(Word_1,Word_2)
PrintF("Jaro Distance=%U%E%E",result)
 
SCopy(Word_1,"DIXONZEILANE") SCopy(Word_2,"DICKSONXZEIDONE")
PrintF("%S - %S%E",Word_1,Word_2)
result=JaroDistance(Word_1,Word_2)
Line 147 ⟶ 198:
PrintF("Jaro Distance=%U%E%E",result)
RETURN
</syntaxhighlight>
</lang>
{{out}}
<pre>MARTHA, MARHTA: 94
Line 155 ⟶ 206:
 
=={{header|Ada}}==
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO;
 
procedure Jaro_Distances is
Line 245 ⟶ 296:
Show_Jaro ("JELLYFISH", "SMELLYFISH");
Show_Jaro (S1 (3 .. 8), S1 (13 .. 18));
end Jaro_Distances;</langsyntaxhighlight>
 
{{out}}
Line 255 ⟶ 306:
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
<syntaxhighlight lang="arm assembly">
<lang ARM Assembly>
 
/* ARM assembly Raspberry PI */
Line 609 ⟶ 660:
 
 
</syntaxhighlight>
</lang>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">loop [
["MARTHA" "MARHTA"]
["DIXON" "DICKSONX"]
["JELLYFISH" "SMELLYFISH"]
] 'pair ->
print [pair "-> Jaro similarity:" round.to: 3 jaro first pair last pair]</syntaxhighlight>
 
{{out}}
 
<pre>[MARTHA MARHTA] -> Jaro similarity: 0.944
[DIXON DICKSONX] -> Jaro similarity: 0.767
[JELLYFISH SMELLYFISH] -> Jaro similarity: 0.896</pre>
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
<lang AWK>
# syntax: GAWK -f JARO_DISTANCE.AWK
BEGIN {
Line 665 ⟶ 731:
function max(x,y) { return((x > y) ? x : y) }
function min(x,y) { return((x < y) ? x : y) }
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 673 ⟶ 739:
0.8962963 'JELLYFISH' 'SMELLYFISH'
</pre>
 
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<syntaxhighlight lang="bbcbasic"> PRINT "Jaro similarity between the two strings:"
PROCDescribeJaro("MARTHA", "MARHTA")
PROCDescribeJaro("DIXON", "DICKSONX")
PROCDescribeJaro("JELLYFISH", "SMELLYFISH")
PROCDescribeJaro("DWAYNE", "DUANE")
PROCDescribeJaro("a", "b")
PROCDescribeJaro("", "")
END
 
DEF FNMax(a, b)=(a + b + ABS(a - b)) / 2
DEF FNMin(a, b)=(a + b - ABS(a - b)) / 2
 
DEF PROCDescribeJaro(word1$, word2$)
LOCAL d%, i%, j%, k%, l1%, l2%, m%, t%
 
PRINT " '" word1$ "' and '" word2$ "'" TAB(30) "= ";
IF word1$ == "" IF word2$ == "" PRINT;1 : ENDPROC
l1%=LENword1$
l2%=LENword2$
IF l1% < l2% SWAP l1%, l2% SWAP word1$, word2$
 
d%=l1% / 2 - 1
j%=1
FOR i%=1 TO l2%
IF MID$(word2$, i%, 1) == MID$(word1$, j%, 1) THEN
m%+=1
MID$(word1$, j%)=" "
ELSE
FOR k%=FNMax(1, i% - d%) TO FNMin(l1%, i% + d%)
IF MID$(word2$, i%, 1) == MID$(word1$, k%, 1) THEN
t%+=1
m%+=1
MID$(word1$, k%)=" "
IF k% > j% j%=k%
ENDIF
NEXT
ENDIF
j%+=1
NEXT
IF m% == 0 THEN
PRINT;0
ELSE
PRINT;(m% / l2% + m% / l1% + ((m% - (t% >> 1)) / m%)) / 3
ENDIF
ENDPROC</syntaxhighlight>
{{out}}
<pre>Jaro similarity between the two strings:
'MARTHA' and 'MARHTA' = 0.944444444
'DIXON' and 'DICKSONX' = 0.766666667
'JELLYFISH' and 'SMELLYFISH' = 0.896296296
'DWAYNE' and 'DUANE' = 0.822222222
'a' and 'b' = 0
'' and '' = 1</pre>
 
=={{header|C}}==
<langsyntaxhighlight Clang="c">#include <stdlib.h>
#include <string.h>
#include <ctype.h>
Line 764 ⟶ 886:
printf("%f\n", jaro("DIXON", "DICKSONX"));
printf("%f\n", jaro("JELLYFISH", "SMELLYFISH"));
}</langsyntaxhighlight>
{{out}}
<pre>
Line 770 ⟶ 892:
0.766667
0.896296
</pre>
 
=={{header|C#}}==
{{trans|Java}}
<syntaxhighlight lang="C#">
using System;
 
public class JaroDistance {
public static double Jaro(string s, string t) {
int s_len = s.Length;
int t_len = t.Length;
 
if (s_len == 0 && t_len == 0) return 1;
 
int match_distance = Math.Max(s_len, t_len) / 2 - 1;
 
bool[] s_matches = new bool[s_len];
bool[] t_matches = new bool[t_len];
 
int matches = 0;
int transpositions = 0;
 
for (int i = 0; i < s_len; i++) {
int start = Math.Max(0, i - match_distance);
int end = Math.Min(i + match_distance + 1, t_len);
 
for (int j = start; j < end; j++) {
if (t_matches[j]) continue;
if (s[i] != t[j]) continue;
s_matches[i] = true;
t_matches[j] = true;
matches++;
break;
}
}
 
if (matches == 0) return 0;
 
int k = 0;
for (int i = 0; i < s_len; i++) {
if (!s_matches[i]) continue;
while (!t_matches[k]) k++;
if (s[i] != t[k]) transpositions++;
k++;
}
 
return (((double)matches / s_len) +
((double)matches / t_len) +
(((double)matches - transpositions / 2.0) / matches)) / 3.0;
}
 
public static void Main(string[] args) {
Console.WriteLine(Jaro("MARTHA", "MARHTA"));
Console.WriteLine(Jaro("DIXON", "DICKSONX"));
Console.WriteLine(Jaro("JELLYFISH", "SMELLYFISH"));
}
}
</syntaxhighlight>
{{out}}
<pre>
0.944444444444445
0.766666666666667
0.896296296296296
 
</pre>
 
=={{header|C++}}==
{{trans|C}}
<langsyntaxhighlight lang="cpp">#include <algorithm>
#include <iostream>
#include <string>
Line 822 ⟶ 1,008:
cout << jaro("JELLYFISH", "SMELLYFISH") << endl;
return 0;
}</langsyntaxhighlight>
 
=={{header|Clojure}}==
<langsyntaxhighlight lang="clojure">
(ns test-project-intellij.core
(:gen-class))
Line 907 ⟶ 1,093:
(println (jaro "DIXON" "DICKSONX"))
(println (jaro "JELLYFISH" "SMELLYFISH"))
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 914 ⟶ 1,100:
0.8962963
</pre>
 
=={{header|CLU}}==
{{trans|C}}
<syntaxhighlight lang="clu">max = proc [T: type] (a, b: T) returns (T)
where T has lt: proctype (T,T) returns (bool)
if a<b then return(b) else return(a) end
end max
 
min = proc [T: type] (a, b: T) returns (T)
where T has lt: proctype (T,T) returns (bool)
if a<b then return(a) else return(b) end
end min
 
jaro = proc (s1, s2: string) returns (real)
s1_len: int := string$size(s1)
s2_len: int := string$size(s2)
if s1_len = 0 & s2_len = 0 then return(1.0)
elseif s1_len = 0 | s2_len = 0 then return(0.0)
end
 
dist: int := max[int](s1_len, s2_len)/2 - 1
s1_match: array[bool] := array[bool]$fill(1,s1_len,false)
s2_match: array[bool] := array[bool]$fill(1,s2_len,false)
 
matches: real := 0.0
transpositions: real := 0.0
for i: int in int$from_to(1, s1_len) do
start: int := max[int](1, i-dist)
end_: int := min[int](i+dist, s2_len)
for k: int in int$from_to(start, end_) do
if s2_match[k] then continue end
if s1[i] ~= s2[k] then continue end
s1_match[i] := true
s2_match[k] := true
matches := matches + 1.0
break
end
end
 
if matches=0.0 then return(0.0) end
k: int := 1
for i: int in int$from_to(1, s1_len) do
if ~s1_match[i] then continue end
while ~s2_match[k] do k := k + 1 end
if s1[i] ~= s2[k] then
transpositions := transpositions + 1.0
end
k := k+1
end
 
transpositions := transpositions / 2.0
return( ((matches / real$i2r(s1_len)) +
(matches / real$i2r(s2_len)) +
((matches - transpositions) / matches)) / 3.0)
end jaro
 
start_up = proc ()
po: stream := stream$primary_output()
stream$putl(po, f_form(jaro("MARTHA", "MARHTA"), 1, 6))
stream$putl(po, f_form(jaro("DIXON", "DICKSONX"), 1, 6))
stream$putl(po, f_form(jaro("JELLYFISH", "SMELLYFISH"), 1, 6))
end start_up</syntaxhighlight>
{{out}}
<pre>0.944444
0.766667
0.896296</pre>
 
=={{header|COBOL}}==
{{trans|Java}}
<langsyntaxhighlight lang="cobol">
identification division.
program-id. JaroDistance.
Line 1,016 ⟶ 1,270:
((matches - transpositions / 2) / matches)) / 3
.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,026 ⟶ 1,280:
=={{header|CoffeeScript}}==
{{trans|C++}}
<langsyntaxhighlight lang="coffeescript">jaro = (s1, s2) ->
l1 = s1.length
l2 = s2.length
Line 1,055 ⟶ 1,309:
console.log jaro "MARTHA", "MARHTA"
console.log jaro "DIXON", "DICKSONX"
console.log jaro "JELLYFISH", "SMELLYFISH"</langsyntaxhighlight>
{{Out}}
<pre>0.9444444444444445
Line 1,063 ⟶ 1,317:
=={{header|Crystal}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="ruby">def jaro(s, t)
return 1.0 if s == t
Line 1,107 ⟶ 1,361:
JELLYFISH SMELLYFISH
).each_slice(2) { |(s ,t)| puts "jaro(#{s}, #{t}) = #{"%.10f" % jaro(s, t)}" }
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,117 ⟶ 1,371:
=={{header|D}}==
{{trans|Kotlin}}
<langsyntaxhighlight Dlang="d">auto jaro(in string s1, in string s2) {
int s1_len = cast(int) s1.length;
int s2_len = cast(int) s2.length;
Line 1,156 ⟶ 1,410:
writeln(jaro( "DIXON", "DICKSONX"));
writeln(jaro("JELLYFISH", "SMELLYFISH"));
}</langsyntaxhighlight>
<pre>0.944444
0.766667
0.896296</pre>
 
=={{header|Delphi}}==
See [https://rosettacode.org/wiki/Jaro_distance#Pascal Pascal].
 
=={{header|Elixir}}==
{{trans|Ruby}}
{{works with|Elixir|1.3}}
<langsyntaxhighlight lang="elixir">defmodule Jaro do
def distance(s, t) when is_binary(s) and is_binary(t), do:
distance(to_charlist(s), to_charlist(t))
Line 1,221 ⟶ 1,478:
|> Enum.each(fn [s,t] ->
:io.format "jaro(~s, ~s) = ~.10f~n", [inspect(s), inspect(t), Jaro.distance(s, t)]
end)</langsyntaxhighlight>
 
{{out}}
Line 1,232 ⟶ 1,489:
Elixir has a built-in function (<code>String.jaro_distance</code>).
 
=={{header|Emacs Lisp}}==
{{trans|Python}}
<syntaxhighlight lang="lisp">
(let ()
(defun jaro (s1 s2)
(let (mw mflags1 mflags2 fn-reset-mflags fn-reset-all-mflags fn-cnt-trans)
(setq mflags1 (make-vector (length s1) nil))
(setq mflags2 (make-vector (length s2) nil))
(setq mw (1- (/ (max (length s1) (length s2)) 2)))
(setq fn-reset-mflags
(lambda (idx)
(let ((start (max 0 (- idx mw)))
(end (min (1- (length s2)) (+ idx mw))))
(cl-loop for i from start to end do
(when (and (not (elt mflags1 idx))
(not (elt mflags2 i)))
(when (equal (elt s1 idx) (elt s2 i))
(aset mflags1 idx 't)
(aset mflags2 i 't) ) ) ) ) ) )
(setq fn-reset-all-mflags
(lambda ()
(dotimes (idx (length s1))
(funcall fn-reset-mflags idx) ) ) )
(setq fn-cnt-trans
(lambda ()
(let ((cur2 0) (transposition 0))
(dotimes (cur1 (length s1))
(when (aref mflags1 cur1)
(while (not (aref mflags2 cur2))
(setq cur2 (1+ cur2)) )
(when (not (equal (aref s1 cur1)
(aref s2 cur2)))
(setq transposition (1+ transposition)) )
(setq cur2 (1+ cur2))
)
)
transposition ) ) )
(funcall fn-reset-all-mflags)
(let ((m (seq-count (lambda (f) f) mflags1))
(tr (funcall fn-cnt-trans)))
;;(message "matches: %s, transposition: %s, |s1|: %d |s2|: %d" m tr (length s1) (length s2))
(if (= m 0)
0
(progn (/ (+ (/ (float m) (length s1)) (/ (float m) (length s2)) (/ (float (- m (/ (float tr) 2))) m) ) 3))
) ) ) )
 
(let ((params '(("MARTHA" "MARHTA")
("DIXON" "DICKSONX")
("JELLYFISH" "SMELLYFISH"))))
(dolist (p params)
(message "jaro(%s, %s) = %f"
(nth 0 p) (nth 1 p)
(jaro (nth 0 p) (nth 1 p)))
)
)
)
 
</syntaxhighlight>
 
{{out}}
<pre>
jaro(MARTHA, MARHTA) = 0.944444
jaro(DIXON, DICKSONX) = 0.766667
jaro(JELLYFISH, SMELLYFISH) = 0.896296
</pre>
 
=={{header|F_Sharp|F#}}==
<syntaxhighlight lang="fsharp">
// Calculate Jaro distance of 2 strings. Nigel Galloway: August 7th., 2020
let fG n g=Seq.map2(fun n g->if g=1 then Some n else None) n g |> Seq.choose id
let J (n:string) (g:string)=
let s1,s2=n.Length,g.Length
let w,m1,m2=(max s1 s2)/2-1,Array.zeroCreate<int>s1,Array.zeroCreate<int>s2
g|>Seq.iteri(fun i g->match [max(i-w) 0..min(i+w)(s1-1)]|>Seq.tryFind(fun i->n.[i]=g&&m1.[i]=0) with Some n->m1.[n]<-1;m2.[i]<-1 |_->())
let t=float(Seq.fold2(fun Σ n g->Σ + (if n<>g then 1 else 0)) 0 (fG n m1) (fG g m2))/2.0
let m=float(m2|>Array.sum) in if m=0.0 then m else ((m/float s1)+(m/float s2)+((m-t)/m))/3.0
 
printfn "MARTHA MARHTA->%f" (J "MARTHA" "MARHTA")
printfn "DIXON DICKSONX->%f" (J "DIXON" "DICKSONX")
printfn "JELLYFISH SMELLYFISH->%f" (J "JELLYFISH" "SMELLYFISH")
</syntaxhighlight>
{{out}}
<pre>
MARTHA MARHTA->0.944444
DIXON DICKSONX->0.766667
JELLYFISH SMELLYFISH->0.896296
</pre>
=={{header|Factor}}==
{{works with|Factor|0.99 development release 2019-03-17+}}
<langsyntaxhighlight lang="factor">USING: formatting fry generalizations kernel locals make math
math.order sequences sequences.extras ;
IN: rosetta-code.jaro-distance
Line 1,267 ⟶ 1,613:
] 2 4 mnapply ;
 
MAIN: jaro-demo</langsyntaxhighlight>
{{out}}
<pre>
Line 1,277 ⟶ 1,623:
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">' version 09-10-2016
' compile with: fbc -s console
 
Line 1,333 ⟶ 1,679:
Print : Print "hit any key to end program"
Sleep
End</langsyntaxhighlight>
{{out}}
<pre> jaro (MARTHA, MARHTA) = 0.9444444444444444
Line 1,340 ⟶ 1,686:
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 1,408 ⟶ 1,754:
fmt.Printf("%f\n", jaro("DIXON", "DICKSONX"))
fmt.Printf("%f\n", jaro("JELLYFISH", "SMELLYFISH"))
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,417 ⟶ 1,763:
 
=={{header|Haskell}}==
<langsyntaxhighlight Haskelllang="haskell">import Data.List (sortBy, elemIndex, intercalate, sortOn)
import Data.Ord (comparing)
import Text.Printf (printf)
import Data.Maybe (mapMaybe)
import Text.Printf (printf)
 
---------------------- JARO DISTANCE ---------------------
 
jaro :: Ord a => [a] -> [a] -> Float
jaro x y =
let| f0 == (fromIntegralm .= length)0
| otherwise =
[m, t] = [f, fromIntegral . transpositions] <*> [matches x y]
(1 / 3)
[s1, s2] = [f] <*> [x, y]
* ( (m / s1) + (m / s2) + ((m - t) / m))
in case m of
where
0 -> 0
f = fromIntegral . length
_ -> (1 / 3) * ((m / s1) + (m / s2) + ((m - t) / m))
[m, t] =
[f, fromIntegral . transpositions]
<*> [matches x y]
[s1, s2] = [f] <*> [x, y]
 
matches :: Eq a => [a] -> [a] -> [(Int, a)]
matches s1 s2 =
let [(l1, xs), (l2, ys)] =
sortOn
sortBy (comparing fst) ((length >>= (,)) <$> [s1, s2])
fst
((length >>= (,)) <$> [s1, s2])
r = quot l2 2 - 1
in mapMaybe
( \(c, n) ->
-- Initial chars out of range ?
 
->
let offset = max 0 (n - (r + 1))
in -- Any offset for this char within range.
in elemIndex c (drop offset (take (n + r) ys)) >>=
>>= (\i -> Just (offset + i, c)))
(zip xs [1 ..])
(zip xs [1 ..])
 
transpositions :: Ord a => [(Int, a)] -> Int
transpositions = length . filter (uncurry (>)) . (zip <*> tail)
length
. filter (uncurry (>))
. (zip <*> tail)
 
-- TEST --------------------------------------------- TEST -------------------------
main :: IO ()
main =
mapM_ putStrLn $
fmap
(\(s1, s2) -> intercalate " -> " [s1, s2, printf "%.3f\n" $ jaro s1 s2]) <$>
[ ("DWAYNE" \(s1, "DUANE"s2) ->
intercalate
, ("MARTHA", "MARHTA")
, ("DIXON", "DICKSONX -> ")
[s1, s2, printf "%.3f\n" $ jaro s1 s2]
, ("JELLYFISH", "SMELLYFISH")
)
]</lang>
[ ("DWAYNE", "DUANE"),
("MARTHA", "MARHTA"),
("DIXON", "DICKSONX"),
("JELLYFISH", "SMELLYFISH")
]</syntaxhighlight>
{{Out}}
<pre>DWAYNE -> DUANE -> 0.822
Line 1,471 ⟶ 1,833:
{{trans|Kotlin}}
{{works with|Neko|2.1.0}}
<langsyntaxhighlight Haxelang="haxe">class Jaro {
private static function jaro(s1: String, s2: String): Float {
var s1_len = s1.length;
Line 1,509 ⟶ 1,871:
Sys.println(jaro("JELLYFISH", "SMELLYFISH"));
}
}</langsyntaxhighlight>
{{Out}}
<pre>0.944444444444445
0.766666666666667
0.896296296296296</pre>
 
=={{header|IS-BASIC}}==
<syntaxhighlight lang="is-basic">100 PROGRAM "Jaro.bas"
110 DO
120 READ IF MISSING EXIT DO:A$,B$
130 PRINT A$;", ";B$;":";JARO(A$,B$)
140 LOOP
150 DEF JARO(A$,B$)
160 LET J=1:LET M,T,JARO=0:LET S1=LEN(A$):LET S2=LEN(B$)
170 IF S1>S2 THEN
180 LET Z$=A$:LET A$=B$:LET B$=Z$
190 LET Z=S1:LET S1=S2:LET S2=Z
200 END IF
210 LET MAXDIST=INT(S2/2)
220 FOR I=1 TO S1
230 IF A$(I)=B$(J) THEN
240 LET M=M+1:CALL CHANGE(B$," ",J)
250 ELSE
260 FOR K=MAX(1,I-MAXDIST) TO MIN(S2,I+MAXDIST)
270 IF A$(I)=B$(K) THEN
280 LET T=T+1:LET M=M+1:CALL CHANGE(B$," ",K)
290 IF K>J THEN LET J=K
300 END IF
310 NEXT
320 END IF
330 IF J<S2 THEN LET J=J+1
340 NEXT
350 IF M<>0 THEN
360 LET T=INT(T/2)
370 LET JARO=(M/S1+M/S2+((M-T)/M))/3
380 END IF
390 END DEF
400 DEF CHANGE(REF S$,C$,POS)
410 LET S$=S$(:POS-1)&C$&S$(POS+1:)
420 END DEF
430 DATA MARTHA,MARHTA
440 DATA DIXON,DICKSONX
450 DATA JELLYFISH,SMELLYFISH
460 DATA DWAYNE,DUANE</syntaxhighlight>
 
=={{header|J}}==
Line 1,519 ⟶ 1,920:
Implementation:
 
<langsyntaxhighlight Jlang="j">jaro=: dyad define
d=. ((x >.&# y)%2)-1
e=. (x =/y) * d >: |x -/&(i.@#) y
Line 1,529 ⟶ 1,930:
s2=. #y
((m%s1)+(m%s2)+(m-t)%m)%3
)</langsyntaxhighlight>
 
Task examples:
 
<langsyntaxhighlight Jlang="j"> 'MARTHA' jaro 'MARHTA'
0.944444
'DIXON' jaro 'DICKSONX'
0.766667
'JELLYFISH' jaro 'SMELLYFISH'
0.896296</langsyntaxhighlight>
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">public class JaroDistance {
public static double jaro(String s, String t) {
int s_len = s.length();
Line 1,590 ⟶ 1,991:
System.out.println(jaro("JELLYFISH", "SMELLYFISH"));
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,599 ⟶ 2,000:
 
=={{header|jq}}==
{{trans|Wren}}
{{works with|jq}}
def jaro(s1; s2):
'''Works with gojq, the Go implementation of jq'''
<syntaxhighlight lang="jq">def jaro($s1; $s2):
def when(p; q): if p then q else . end;
($s1|length) as $le1
| (s1$s2|length) as $len1le2
| if |$le1 (s2|length)== as0 and $len2le2 == 0 then 1
|elif (( [$len1,le1 $len2]== |0 max )or /$le2 2== -0 1)then as $match_standard0
else ((((if $le2 > $le1 then $le2 else $le1 end) / 2) | floor) - 1) as $dist
| {m:0, p:0}
| {matches: 0, matches2: [], matches2: [], transpos: 0 }
| reduce range(0; $len1) as $l1
| reduce range(.0; s1[$l1:$l1+1]le1) as $t1i (.;
(($i - $dist) | reduceif . < range(0; $len2 then 0 else . end) as $l2start
| (($i + $dist + 1) | if (.; s2[> $l2:le2 then $l2+1]le2 else . end) as $t2stop
| when(.k $t1 == $t2;start
| until(.k >= $stop;
when( ($l2-$l1) <= $match_standard and ($l1-$l2) <= $match_standard;
if (.matches2[.k] or $s1[$i:$i+1] != $s2[.mk:.k+=1]) |not
then | when(.matches1[$l2i] == $l1; .p += 1) ) ) )true
| ((.m-matches2[.p)/2)k] as= $ttrue
| ( (.m/$len1) + (.m/$len2) + (( | .m-$t)/.m)matches ) /+= 31
; | .k = $stop
else .k += 1
end) )
jaro("MARTHA";"MARHTA")
| if .matches == 0 then 0
, jaro("DIXON"; "DICKSONX")
else .k = 0
, jaro("JELLYFISH";"SMELLYFISH")
| reduce range(0; $le1) as $i (.;
if .matches1[$i]
then until(.k >= $le2 or .matches2[.k]; .k += 1)
| if .k < $le2 and ($s1[$i:$i+1] != $s2[.k:.k+1]) then .transpos += 1 else . end
| .k += 1
else .
end )
| .transpos /= 2
| (.matches/$le1 + .matches/$le2 + ((.matches - .transpos)/.matches)) / 3
end
end ;
 
def task:
Output:
[["MARTHA","MARHTA"],
["DIXON", "DICKSONX"],
["JELLYFISH","SMELLYFISH"],
["ABC","DEF"]][]
| (jaro(.[0]; .[1]) * 1000 | floor / 1000) as $d
| "jaro(\(.[0]); \(.[1])) => \($d)";
 
task</syntaxhighlight>
{{out}}
<pre>
jaro(MARTHA; MARHTA) => 0.944
0.9444444444444444
jaro(DIXON; DICKSONX) => 0.766
0.6833333333333332
jaro(JELLYFISH; SMELLYFISH) => 0.896
0.8870370370370371
jaro(ABC; DEF) => 0
</pre>
 
=={{header|Julia}}==
{{works with|Julia|01.65}}
<langsyntaxhighlight lang="julia">function jarodistance(s1::AbstractString, s2::AbstractString)
m = t = p = l1 = l2 = 0
matchstd = max(length(s1), length(s2)) / 2 - 1
for i(i1, c1) in enumerate(s1[1:end])
l1for +=(i2, 1c2) in enumerate(s2)
(c1 == c2) && (abs(i2 - i1) ≤ matchstd) && (m += 1)
l2 = 0
for j in s2[ (c1 == c2) && (i2 == i1) && (p += 1:end])
l2 += 1
if i == j
if abs(l2 - l1) ≤ matchstd m += 1 end
if l2 == l1 p += 1 end
end
end
end
t = (m - p) / 2
d = 1 / 3 * (m / length(s1) + m / length(s2) + (m - t) / m)
return d
end
 
@show jarodistance("MARTHA", "MARHTA")
const testcouples = (("MARTHA", "MARHTA"), ("DIXON", "DICKSONX"), ("JELLYFISH", "SMELLYFISH"))
@show jarodistance("DIXON", "DICKSONX")
for (s1, s2) in testcouples
@show println("jarodistance(\"$s1\JELLYFISH", \"$s2\SMELLYFISH") = ", @sprintf "%2.2f" jarodistance(s1, s2))
</syntaxhighlight>
end</lang>
 
{{out}}
<pre>
<pre>jarodistance("MARTHA", "MARHTA") = 0.94
jarodistance("DIXONMARTHA", "DICKSONXMARHTA") = 0.689444444444444444
jarodistance("JELLYFISHDIXON", "SMELLYFISHDICKSONX") = 0.89</pre>6833333333333332
jarodistance("JELLYFISH", "SMELLYFISH") = 0.8870370370370371
</pre>
 
=={{header|Kotlin}}==
{{trans|Java}}
<langsyntaxhighlight lang="scala">object Jaro {
fun distance(s1: String, s2: String): Double {
val s1_len = s1.length
Line 1,700 ⟶ 2,118:
println(Jaro.distance("DIXON", "DICKSONX"))
println(Jaro.distance("JELLYFISH", "SMELLYFISH"))
}</langsyntaxhighlight>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">ClearAll[JaroDistance]
JaroDistance[s_String, t_String] := Module[{slen, tlen, maxdistance, smatches, tmatches, matches, transpositions, start, end, k, schar, tchar},
slen = StringLength[s];
tlen = StringLength[t];
schar = Characters[s];
tchar = Characters[t];
If[slen == tlen == 0,
1
,
maxdistance = Floor[Max[slen, tlen]/2] - 1;
smatches = ConstantArray[False, slen];
tmatches = ConstantArray[False, tlen];
matches = transpositions = 0;
Do[
start = Max[0, i - maxdistance];
end = Min[i + maxdistance + 1, tlen];
start = Max[1, i - maxdistance];
end = Min[i + maxdistance + 1, tlen];
Do[
If[! tmatches[[j]],
If[schar[[i]] == tchar[[j]],
smatches[[i]] = True;
tmatches[[j]] = True;
matches++;
Break[];
]
]
,
{j, start, end}
]
,
{i, slen}
];
If[matches == 0,
0
,
k = 1;
Do[
If[smatches[[i]],
While[! tmatches[[k]],
k++;
];
If[schar[[i]] != tchar[[k]],
transpositions++;
];
k++;
]
,
{i, slen}
];
N@(matches/slen + matches/tlen + (matches - transpositions/2)/matches)/3
]
]
]
JaroDistance["DWAYNE", "DUANE"]
JaroDistance["MARTHA", "MARHTA"]
JaroDistance["DIXON", "DICKSONX"]
JaroDistance["JELLYFISH", "SMELLYFISH"]</syntaxhighlight>
{{out}}
<pre>0.822222
0.944444
0.766667
0.896296</pre>
 
=={{header|Nim}}==
{{trans|Kotlin}}
<syntaxhighlight lang="nim">import lenientops
 
func jaro(s1, s2: string): float =
 
if s1.len == 0 and s2.len == 0: return 1
if s1.len == 0 or s2.len == 0: return 0
 
let matchDistance = max(s1.len, s2.len) div 2 - 1
var s1Matches = newSeq[bool](s1.len)
var s2Matches = newSeq[bool](s2.len)
var matches = 0
for i in 0..s1.high:
for j in max(0, i - matchDistance)..min(i + matchDistance, s2.high):
if not s2Matches[j] and s1[i] == s2[j]:
s1Matches[i] = true
s2Matches[j] = true
inc matches
break
if matches == 0: return 0
 
var transpositions = 0.0
var k = 0
for i in ..s1.high:
if not s1Matches[i]: continue
while not s2Matches[k]: inc k
if s1[i] != s2[k]: transpositions += 0.5
inc k
 
result = (matches / s1.len + matches / s2.len + (matches - transpositions) / matches) / 3
 
echo jaro("MARTHA", "MARHTA")
echo jaro("DIXON", "DICKSONX")
echo jaro("JELLYFISH", "SMELLYFISH")</syntaxhighlight>
 
{{out}}
<pre>0.9444444444444445
0.7666666666666666
0.8962962962962964</pre>
 
=={{header|Objeck}}==
{{trans|Java}}
<langsyntaxhighlight lang="objeck">class JaroDistance {
function : Main(args : String[]) ~ Nil {
Jaro("MARTHA", "MARHTA")->PrintLine();
Line 1,753 ⟶ 2,278:
((matches->As(Float) - transpositions/2.0) / matches)) / 3.0;
}
}</langsyntaxhighlight>
 
{{output}}
Line 1,767 ⟶ 2,292:
{{Works with|PARI/GP|2.7.4 and above}}
 
<langsyntaxhighlight lang="parigp">
\\Jaro distance between 2 strings s1 and s2.
\\ 4/12/16 aev
Line 1,803 ⟶ 2,328:
jaroDist("DWAYNE","DUANE");
}
</langsyntaxhighlight>
 
{{Output}}
Line 1,815 ⟶ 2,340:
 
=={{header|Pascal}}==
<langsyntaxhighlight lang="pascal">
program Jaro_distance;
 
uses SysUtils, Math;
 
//converted from C source by /u/bleuge
function ssJaroWinkler(s1, s2: string): double;
var
l1, l2, match_distance, matches, i, k, trans: integer;
bs1, bs2: array[1..255] of boolean; //used to avoid getmem, max string length is 255
begin
l1 := length(s1);
l2 := length(s2);
fillchar(bs1, sizeof(bs1), 0); //set booleans to false
fillchar(bs2, sizeof(bs2), 0);
if l1 = 0 then
if l2 = 0 then exit(1)
else exit(01);
else
match_distance:=(max(l1,l2) div 2)-1;
matches:= exit(0);
match_distance := (max(l1, l2) div 2) - 1;
trans:=0;
matches := 0;
trans := 0;
for i := 1 to l1 do
begin
for k := max(1, i - match_distance) to min(i + match_distance, l2) do
begin
if bs2[k] then continue;
if s1[i]<>s2[k] then continue;
bs1if s1[i]:=true; <> s2[k] then
bs2[k]:=true continue;
bs1[i] := true;
bs2[k] := true;
inc(matches);
break;
end;
end;
if matches = 0 then exit(0);
k:=1 exit(0);
k := 1;
for i := 1 to l1 do
begin
if (bs1[i] = false) then continue;
continue;
while (bs2[k]=false) do inc(k);
ifwhile s1[i]<>s2(bs2[k] then= inc(transfalse); do
inc(k);
if s1[i] <> s2[k] then
inc(trans);
inc(k);
end;
trans := trans div 2;
result := ((matches / l1) + (matches / l2) + ((matches - trans) / matches)) / 3;
end;
 
begin
//test
writeln(formatfloat('0.######', ssJaroWinkler('DWAYNE', 'DUANE')));
writeln(formatfloat('0.######', ssJaroWinkler('MARTHA', 'MARHTA')));
writeln(formatfloat('0.######', ssJaroWinkler('DIXON', 'DICKSONX')));
writeln(formatfloat('0.######', ssJaroWinkler('JELLYFISH', 'SMELLYFISH')));
{$IFNDEF LINUX}readln;{$ENDIF}
</lang>
end.</syntaxhighlight>
{{out}}
<pre>
Line 1,871 ⟶ 2,411:
 
=={{header|Perl}}==
<syntaxhighlight lang ="perl">use List::Util qw(min max)strict;
use warnings;
use List::Util qw(min max);
 
sub jaro {
my ($s, $t) = @_;
my(@s_matches, @t_matches, $matches);
 
myreturn $s_len1 =if length($s) eq $t;
my $t_len = length($t);
 
return 1 if my($s_len, @s) == 0 and(length $t_lens, ==split //, 0$s);
my($t_len, @t) = (length $t, split //, $t);
 
my $match_distance = int(max($s_len, $t_len) / 2) - 1;
 
my @s_matches;
my @t_matches;
 
my @s = split(//, $s);
my @t = split(//, $t);
 
my $matches = 0;
foreach my $i (0 .. $#s) {
 
my $match_distance = int (max($s_len, $t_len) / 2) - 1;
for my $i (0 .. $#s) {
my $start = max(0, $i - $match_distance);
my $end = min($i + $match_distance + 1, $t_len);
for my $j ($start .. $end - 1) {
 
foreach my $j ($start ..next if $endt_matches[$j] -or 1)$s[$i] {ne $t[$j];
($s_matches[$i], $t_matches[$j]) = and(1, next1);
$s[$i]matches++ eqand $t[$j] or nextlast;
$s_matches[$i] = 1;
$t_matches[$j] = 1;
$matches++;
last;
}
}
return 0 unless $matches;
 
return 0 ifmy($k, $matchestranspositions) == (0, 0);
for my $i (0 .. $#s) {
 
my $k next unless = 0$s_matches[$i];
$k++ until $t_matches[$k];
my $transpositions = 0;
$transpositions++ if $s[$i] ne $t[$k];
 
foreach my $i (0 .. $#s) {k++;
$s_matches[$i] or next;
until ($t_matches[$k]) { ++$k }
$s[$i] eq $t[$k] or ++$transpositions;
++$k;
}
( $matches/$s_len + $matches/$t_len + (($matches - $transpositions/2) / $matches) ) / 3;
 
(($matches / $s_len) + ($matches / $t_len) +
(($matches - $transpositions / 2) / $matches)) / 3;
}
 
printf( "%f.3f\n", jaro("MARTHA"@$_[0], @$_[1]) "MARHTA"));for
['MARTHA', 'MARHTA'], ['DIXON', 'DICKSONX'], ['JELLYFISH', 'SMELLYFISH'],
printf("%f\n", jaro("DIXON", "DICKSONX"));
['I repeat myself', 'I repeat myself'], ['', ''];</syntaxhighlight>
printf("%f\n", jaro("JELLYFISH", "SMELLYFISH"));</lang>
{{out}}
<pre>0.944
0.944444767
0.766667896
1.000
0.896296
1.000</pre>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function jaro(string str1, str2)
<span style="color: #008080;">function</span> <span style="color: #000000;">jaro</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">str1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">str2</span><span style="color: #0000FF;">)</span>
str1 = trim(upper(str1))
<span style="color: #000000;">str1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trim</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">upper</span><span style="color: #0000FF;">(</span><span style="color: #000000;">str1</span><span style="color: #0000FF;">))</span>
str2 = trim(upper(str2))
<span style="color: #000000;">str2</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trim</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">upper</span><span style="color: #0000FF;">(</span><span style="color: #000000;">str2</span><span style="color: #0000FF;">))</span>
integer len1 = length(str1),
<span style="color: #004080;">integer</span> <span style="color: #000000;">len1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">str1</span><span style="color: #0000FF;">),</span>
len2 = length(str2),
<span style="color: #000000;">len2</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">str2</span><span style="color: #0000FF;">),</span>
match_distance = floor(max(len1,len2)/2)-1,
<span style="color: #000000;">match_distance</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">len1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">len2</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span>
match_count = 0,
<span style="color: #000000;">match_count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span>
half_transposed = 0
<span style="color: #000000;">half_transposed</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
 
if len1==0 then return len2==0 end if
<span style="color: #008080;">if</span> <span style="color: #000000;">len1</span><span style="color: #0000FF;">==</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">len2</span><span style="color: #0000FF;">==</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
 
-- count the number of matches
<span style="color: #000080;font-style:italic;">-- count the number of matches</span>
sequence m1 = repeat(false,len1),
<span style="color: #004080;">sequence</span> <span style="color: #000000;">m1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #004600;">false</span><span style="color: #0000FF;">,</span><span style="color: #000000;">len1</span><span style="color: #0000FF;">),</span>
m2 = repeat(false,len2)
<span style="color: #000000;">m2</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #004600;">false</span><span style="color: #0000FF;">,</span><span style="color: #000000;">len2</span><span style="color: #0000FF;">)</span>
for i=1 to len1 do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">len1</span> <span style="color: #008080;">do</span>
for k=max(1,i-match_distance)
<span style="color: #008080;">for</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">match_distance</span><span style="color: #0000FF;">)</span>
to min(len2,i+match_distance) do
<span style="color: #008080;">to</span> <span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">len2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">match_distance</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
if not m2[k] then
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">m2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
if str1[i]=str2[k] then
<span style="color: #008080;">if</span> <span style="color: #000000;">str1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">str2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
m1[i] = true
<span style="color: #000000;">m1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
m2[k] = true
<span style="color: #000000;">m2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
match_count += 1
<span style="color: #000000;">match_count</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
exit
end if <span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
if match_count==0 then return 0 end if
<span style="color: #008080;">if</span> <span style="color: #000000;">match_count</span><span style="color: #0000FF;">==</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
-- count the number of half-transpositions
<span style="color: #000080;font-style:italic;">-- count the number of half-transpositions</span>
integer k = 1
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
for i=1 to len1 do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">len1</span> <span style="color: #008080;">do</span>
if m1[i] then
<span style="color: #008080;">if</span> <span style="color: #000000;">m1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
while not m2[k] do k += 1 end while
<span style="color: #008080;">while</span> <span style="color: #008080;">not</span> <span style="color: #000000;">m2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">do</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span> <span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
half_transposed += (str1[i]!=str2[k])
<span style="color: #000000;">half_transposed</span> <span style="color: #0000FF;">+=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">str1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">str2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">])</span>
k += 1
<span style="color: #000000;">k</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
integer transpositions = floor(half_transposed/2),
<span style="color: #004080;">integer</span> <span style="color: #000000;">transpositions</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">half_transposed</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">),</span>
not_transposed = match_count - transpositions
<span style="color: #000000;">not_transposed</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">match_count</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">transpositions</span>
--
<span style="color: #000080;font-style:italic;">--
-- return the average of:
-- return the average of:
-- percentage/fraction of the first string matched,
-- percentage/fraction of the secondfirst string matched, and
-- percentage/fraction of matchesthe thatsecond werestring notmatched, transposed.and
-- percentage/fraction of matches that were not transposed.
--
--</span>
return (match_count/len1 +
<span style="color: #008080;">return</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">match_count</span><span style="color: #0000FF;">/</span><span style="color: #000000;">len1</span> <span style="color: #0000FF;">+</span>
match_count/len2 +
<span style="color: #000000;">match_count</span><span style="color: #0000FF;">/</span><span style="color: #000000;">len2</span> <span style="color: #0000FF;">+</span>
not_transposed/match_count)/3
<span style="color: #000000;">not_transposed</span><span style="color: #0000FF;">/</span><span style="color: #000000;">match_count</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">3</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
 
constant testcouples = {{"CRATE","TRACE"},
<span style="color: #008080;">constant</span> <span style="color: #000000;">testcouples</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #008000;">"CRATE"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"TRACE"</span><span style="color: #0000FF;">},</span>
{"JONES","JOHNSON"},
<span style="color: #0000FF;">{</span><span style="color: #008000;">"JONES"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"JOHNSON"</span><span style="color: #0000FF;">},</span>
{"ABCVWXYZ","CABVWXYZ"},
<span style="color: #0000FF;">{</span><span style="color: #008000;">"ABCVWXYZ"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"CABVWXYZ"</span><span style="color: #0000FF;">},</span>
{"DWAYNE","DUANE"},
<span style="color: #0000FF;">{</span><span style="color: #008000;">"DWAYNE"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"DUANE"</span><span style="color: #0000FF;">},</span>
{"MARTHA", "MARHTA"},
<span style="color: #0000FF;">{</span><span style="color: #008000;">"MARTHA"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"MARHTA"</span><span style="color: #0000FF;">},</span>
{"DIXON", "DICKSONX"},
<span style="color: #0000FF;">{</span><span style="color: #008000;">"DIXON"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"DICKSONX"</span><span style="color: #0000FF;">},</span>
{"JELLYFISH", "SMELLYFISH"}}
<span style="color: #0000FF;">{</span><span style="color: #008000;">"JELLYFISH"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"SMELLYFISH"</span><span style="color: #0000FF;">}}</span>
 
for i=1 to length(testcouples) do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">testcouples</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
string {s1, s2} = testcouples[i]
<span style="color: #004080;">string</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">s1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">s2</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">testcouples</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
printf(1,"%f <== jaro(\"%s\", \"%s\")\n",{jaro(s1,s2),s1,s2})
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%f &lt;== jaro(\"%s\", \"%s\")\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">jaro</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s2</span><span style="color: #0000FF;">),</span><span style="color: #000000;">s1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s2</span><span style="color: #0000FF;">})</span>
end for</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 2,012 ⟶ 2,539:
 
{{Works with|Python|3}}
<langsyntaxhighlight lang="python">'''Jaro distance'''
 
from __future__ import division
Line 2,075 ⟶ 2,602:
 
if __name__ == '__main__':
main()</langsyntaxhighlight>
{{out}}
<pre>jaro('MARTHA', 'MARHTA') = 0.9444444444
Line 2,085 ⟶ 2,612:
{{Trans|Haskell}}
{{Works with|Python|3}}
<langsyntaxhighlight lang="python">'''Jaro distance between two strings'''
 
from functools import reduce
import itertools
 
 
# --------------------- JARO FUNCTION ----------------------
 
# jaro :: String -> String -> Float
Line 2,095 ⟶ 2,624:
'''The Jaro distance between two strings.'''
def go(s1, s2):
m, t = fanArrowap(compose(Tuple, len)(transpositionSum)(
matches(s1, s2)transpositionSum
)(matches(s1, s2))
return 0 if 0 == m else (
(1 / 3) * ((m / len(s1)) + (m / len(s2)) + ((m - t) / m))
m / len(s2)
) + ((m - t) / m))
)
return lambda y: go(x, y)
 
 
# -------------------------- TEST --------------------------
# main :: IO ()
def main():
'''TestsSample word pairs'''
 
print(
tabulatedfTable('Jaro distances:\n')(str)(showPrecision(3))(
showPrecision(3)
)(
uncurry(jaro)
)([
Line 2,120 ⟶ 2,654:
 
 
# JARO HELPER FUNCTIONS ----------------- JARO HELPER FUNCTIONS ------------------
 
 
# transpositionSum :: [(Int, Char)] -> Int
Line 2,138 ⟶ 2,671:
 
[(_, xs), (l2, ys)] = sorted(map(
fanArrowap(compose(Tuple, len))(list), [s1, s2]
))
r = l2 // 2 - 1
Line 2,158 ⟶ 2,691:
 
 
# GENERIC FUNCTIONS ------------------- GENERIC FUNCTIONS --------------------
 
# Just :: a -> Maybe a
def Just(x):
'''Constructor for an inhabited Maybe (option type) value.'''
Wrapper containing the result of a computation.
'''
return {'type': 'Maybe', 'Nothing': False, 'Just': x}
 
Line 2,168 ⟶ 2,703:
# Nothing :: Maybe a
def Nothing():
'''Constructor for an empty Maybe (option type) value.'''
Empty wrapper returned where a computation is not possible.
'''
return {'type': 'Maybe', 'Nothing': True}
 
 
# composeTuple (<<<,) :: (ba -> c)b -> (a ->, b) -> a -> c
def composeTuple(gx):
'''Constructor for a pair of values,
'''Function composition.'''
possibly of two different types.
return lambda f: lambda x: g(f(x))
'''
def go(y):
return (
x + (y,)
) if isinstance(x, tuple) else (x, y)
return go
 
 
# ap :: (a -> b -> c) -> (a -> b) -> a -> c
def ap(f):
'''Applicative instance for functions.
'''
def go(g):
def fxgx(x):
return f(x)(
g(x)
)
return fxgx
return go
 
 
# compose :: ((a -> a), ...) -> (a -> a)
def compose(*fs):
'''Composition, from right to left,
of a series of functions.
'''
def go(f, g):
def fg(x):
return f(g(x))
return fg
return reduce(go, fs, lambda x: x)
 
 
Line 2,181 ⟶ 2,749:
# drop :: Int -> String -> String
def drop(n):
'''The sublist of xs beginning at (zero-based) index n.'''
(zero-based) index n.
'''
def go(xs):
if isinstance(xs, (list, tuple, str)):
return xs[n:]
else:
take(n)(xs)
return xs
return lambda xs: go(xs)
 
 
Line 2,195 ⟶ 2,765:
'''Just the index of the first element in xs
which is equal to x,
or Nothing if there is no such element.'''
'''
def go(xs):
try:
Line 2,201 ⟶ 2,772:
except ValueError:
return Nothing()
return lambda xs: go(xs)
 
 
# fanArrow (&&&) :: (a -> b) -> (a -> c) -> (a -> (b, c))
def fanArrow(f):
'''A tuple of the outputs of two separate functions
applied to the same value.'''
return lambda g: lambda x: (f(x), g(x))
 
 
# fst :: (a, b) -> a
def fst(tpl):
'''First componentmember of a tuplepair.'''
return tpl[0]
 
Line 2,221 ⟶ 2,785:
'''Either the default value v, if m is Nothing,
or the application of f to x,
where the Maybe valuem is Just(x).'''
'''
return lambda f: lambda m: v if m.get('Nothing') else (
return lambda f: lambda f(m.get: v if ('Just'))
None is m or m.get('Nothing')
)
) else f(m.get('Just'))
 
 
Line 2,234 ⟶ 2,799:
 
 
# tabulatedfTable :: String -> (a -> String) ->
# (b -> String) -> (a -> (b) -> String)[a] -> String
def fTable(s):
# (a -> b) -> [a] -> String
def tabulated(s):
'''Heading -> x display function -> fx display function ->
f -> value listxs -> tabular string.'''
'''
def go(xShow, fxShow, f, xs):
def w = max(map(compose(len)gox(xShow), xs)):
returndef s + '\n' + '\n'.joingofx(fxShow):
xShow(x).rjust(w,def ' ') + ' -> ' + fxShowgof(f(x)) for x in xs:
def goxs(xs):
ys = [xShow(x) for x in xs]
return lambda xShow: lambda fxShow: lambda f: lambda xs: go(
xShow, fxShow, f w = max(map(len, xsys))
 
)
def arrowed(x, y):
return y.rjust(w, ' ') + (
' -> ' + fxShow(f(x))
)
return s + '\n' + '\n'.join(
map(arrowed, xs, ys)
)
return goxs
return gof
return gofx
return gox
 
 
Line 2,254 ⟶ 2,829:
def take(n):
'''The prefix of xs of length n,
or xs itself if n > length xs.'''
'''
islice = itertools.islice
 
return lambda xs: (
def go(xs[0):n]
ifreturn isinstance(xs, list)
else list(islice(xs, xs[0:n))]
if isinstance(xs, (list, tuple))
)
else list(islice(xs, n))
)
return go
 
 
Line 2,273 ⟶ 2,852:
# MAIN ---
if __name__ == '__main__':
main()</langsyntaxhighlight>
{{Out}}
<pre>Jaro distances:
Line 2,289 ⟶ 2,868:
Returns an exact value for the Jaro distance.
 
<langsyntaxhighlight lang="racket">#lang racket/base
;; {{trans|C}}
(require data/bit-vector)
Line 2,356 ⟶ 2,935:
(exact->inexact (jaro-distance "DIXON" "DICKSONX")); 0.766667
(jaro-distance "JELLYFISH" "SMELLYFISH"); 0.896296
(exact->inexact (jaro-distance "JELLYFISH" "SMELLYFISH"))); 0.896296</langsyntaxhighlight>
 
{{out}}
Line 2,370 ⟶ 2,949:
(formerly Perl 6)
{{trans|Perl}}
<syntaxhighlight lang="raku" perl6line>sub jaro ($s, $t) {
 
return 1 if $s eq $t;
 
my $s_lens-len = + my @s = $s.comb;
my $t_lent-len = + my @t = $t.comb;
my $match-distance = ($s-len max $t-len) div 2 - 1;
 
my $match_distance = ($s_len max $t_len) div 2 - 1;
 
my @s_matches;
my @t_matches;
my $matches = 0;
 
my ($matches, @s-matches, @t-matches);
for ^@s -> $i {
my $start = 0 max $i - $match-distance;
 
my $startend = 0 max= $i + $match-distance min ($match_distancet-len - 1);
my $end = $i + $match_distance min $t_len;
 
for $start .. $end -> $j {
next if @t_matchest-matches[$j] andor next@s[$i] ne @t[$j];
(@s-matches[$i] eq, @t-matches[$j]) = or(1, next1);
@s_matches[$i]matches++ =and 1last;
@t_matches[$j] = 1;
$matches++;
last;
}
}
return 0 unless $matches;
 
returnmy 0 if($k, $matchestranspositions) == (0, 0);
 
my $k = 0;
my $transpositions = 0;
 
for ^@s -> $i {
next unless @s_matchess-matches[$i] or next;
$k++ until @t_matchest-matches[$k] { ++$k };
$transpositions++ if @s[$i] eqne @t[$k] or ++$transpositions;
++$k++;
}
 
( $matches /$s-len + $matches/$s_lent-len + (($matches - $transpositions/2) / $t_lenmatches) +) / 3
(($matches - $transpositions / 2) / $matches)) / 3;
}
 
say jaro(.key, .value).fmt: '%.3f' for
printf("%f\n", jaro("MARTHA", "MARHTA"));
'MARTHA' => 'MARHTA', 'DIXON' => 'DICKSONX', 'JELLYFISH' => 'SMELLYFISH',
printf("%f\n", jaro("DIXON", "DICKSONX"));
'I repeat myself' => 'I repeat myself', '' => '';
printf("%f\n", jaro("JELLYFISH", "SMELLYFISH"));</lang>
</syntaxhighlight>
{{out}}
<pre>0.944
0.944444767
0.766667896
1.000
0.896296
1.000</pre>
 
=={{header|REXX}}==
<langsyntaxhighlight lang="rexx">/*REXX program computes the Jaro distance between two strings (or a list of strings).*/
@.= /*define a default for the @. array. */
parse arg @.1 /*obtain an optional character string. */
Line 2,432 ⟶ 2,999:
@.3= 'JELLYFISH SMELLYFISH'
@.4= 'DWAYNE DUANE'
end /* [↑] embedded blanks are listshown as is.*/
 
do j=1 while @.j\=='' /*process all the strings in the list. */
do j=1 while @.j\=='' /*process all the strings in the list. */
d= jaroD(@.j)
d= jaroD(@.j)
say 'Jaro distance is ' format(d, , 8) " for strings: " @.j
end say 'Jaro /*j*/distance is ' format(d, , 8) " for strings: " /* └──── digits past the decimal point@.*/j
exit end /*j*/ /*stick a└──── forkdigits inpast it,the decimal we're all donepoint. */
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
jaroD: procedure; arg s.1 s.2 .; L1= length(s.1); L2= length(s.2); m= 0
if L1==0 | L2==0 then return 0 /*check if any string is a null string.*/
f= max(L1, L2) % 2 - 1 /*calculate furthest distanced allowed.*/
r.=0 0 /* [↓] see if the char is near enough.*/
do k=1 for L1; p= pos( substr(s.1, k, 1), s.2, max(1, k-f) )
r.k= p
Line 2,448 ⟶ 3,016:
else r.k= 0 /* ··· otherwise, don't count it.*/
end /*k*/
t= 0
do o=1 for L1; om= o - 1; if r.o==0 | r.om==0 then iterate
if pos( substr(s.1, o, 1), s.2)==0 then iterate
Line 2,455 ⟶ 3,023:
 
if m==0 then return 0
return (m/L1 + m/L2 + (m-t)/m) / 3</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
Line 2,465 ⟶ 3,033:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project : Jaro distance
 
Line 2,515 ⟶ 3,083:
b = temp
return [a, b]
</syntaxhighlight>
</lang>
Output:
<pre>
Line 2,524 ⟶ 3,092:
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">def jaro(s, t)
return 1.0 if s == t
Line 2,571 ⟶ 3,139:
).each_slice(2) do |s,t|
puts "jaro(#{s.inspect}, #{t.inspect}) = #{'%.10f' % jaro(s, t)}"
end</langsyntaxhighlight>
{{out}}
<pre>
Line 2,581 ⟶ 3,149:
=={{header|Rust}}==
{{trans|C++}}
<langsyntaxhighlight lang="rust">use std::cmp;
 
pub fn jaro(s1: &str, s2: &str) -> f64 {
Line 2,621 ⟶ 3,189:
let pairs = [("MARTHA", "MARHTA"), ("DIXON", "DICKSONX"), ("JELLYFISH", "SMELLYFISH")];
for p in pairs.iter() { println!("{}/{} = {}", p.0, p.1, jaro(p.0, p.1)); }
}</langsyntaxhighlight>
{{Out}}
<pre>MARTHA/MARHTA = 0.9444444444444445
Line 2,629 ⟶ 3,197:
=={{header|Scala}}==
{{trans|Java}}
<langsyntaxhighlight lang="scala">object Jaro extends App {
 
def distance(s1: String, s2: String): Double = {
Line 2,665 ⟶ 3,233:
val strings = List(("MARTHA", "MARHTA"), ("DIXON", "DICKSONX"), ("JELLYFISH", "SMELLYFISH"))
strings.foreach { s => println(distance(s._1, s._2)) }
}</langsyntaxhighlight>
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">func jaro(s, t) {
 
return 1 if (s == t)
Line 2,718 ⟶ 3,286:
] {
say "jaro(#{pair.map{.join.dump}.join(', ')}) = #{'%.10f' % jaro(pair...)}"
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,729 ⟶ 3,297:
Here we use the [https://ideas.repec.org/c/boc/bocode/s457850a.html jarowinkler] package from SSC. To install the package, type
 
<syntaxhighlight lang ="stata">ssc install jarowinkler</langsyntaxhighlight>
 
Now the program for the task:
 
<langsyntaxhighlight lang="stata">clear
input str20 a str20 b
DWAYNE DUANE
Line 2,744 ⟶ 3,312:
format %8.3f jaro
format %-20s a b
list a b jaro</langsyntaxhighlight>
 
'''Output'''
Line 2,758 ⟶ 3,326:
 
=={{header|Swift}}==
<langsyntaxhighlight Swiftlang="swift"> func jaroWinklerMatch(_ s: String, _ t: String) -> Double {
let s_len: Int = s.count
let t_len: Int = t.count
Line 2,847 ⟶ 3,415:
print("DIXON/DICKSONX:", jaroWinklerMatch("DIXON", "DICKSONX"))
print("JELLYFISH/SMELLYFISH:", jaroWinklerMatch("JELLYFISH", "SMELLYFISH"))
</syntaxhighlight>
</lang>
 
{{out}}
Line 2,858 ⟶ 3,426:
 
=={{header|Tcl}}==
<langsyntaxhighlight Tcllang="tcl">proc jaro {s1 s2} {
set l1 [string length $s1]
set l2 [string length $s2]
Line 2,895 ⟶ 3,463:
} {
puts "[jaro $s $t]:\t$s / $t"
}</langsyntaxhighlight>
 
{{out}}
Line 2,904 ⟶ 3,472:
 
=={{header|Turbo-Basic XL}}==
<langsyntaxhighlight lang="turbobasic">
10 DIM Word_1$(20), Word_2$(20), Z$(20)
11 CLS
Line 2,920 ⟶ 3,488:
12050 IF Word_1$(I,I)=Word_2$(J,J) THEN M=M+1: Word_2$(J,J)=" ": GO# JMP_JWD
12060 Max=1 : IF Max<(I-L) THEN Max=I-L
12070 Min=S2 : IF Min>(I+L-1) THEN Min=I+L-1
12080 FOR K=Max TO Min
12090 IF Word_1$(I,I)=Word_2$(K,K) THEN N=N+1: M=M+1: Word_2$(K,K)=" ": IF K>J THEN J=K
Line 2,946 ⟶ 3,514:
12310 ? "Jaro Winkler Distance=";Result
12320 ENDPROC
</syntaxhighlight>
</lang>
{{out}}
<pre>MARTHA, MARHTA: 0.9444444433
Line 2,953 ⟶ 3,521:
 
=={{header|VBA}}==
<syntaxhighlight lang="vb">
<lang vb>
Option Explicit
 
Line 2,998 ⟶ 3,566:
JaroWinkler = JaroWinkler + (1 - JaroWinkler) * l * WorksheetFunction.Min(0.25, p)
End Function
</syntaxhighlight>
</lang>
 
=={{header|V (Vlang)}}==
 
{{trans|Python}}
<syntaxhighlight lang="v (vlang)">import math
 
fn jaro(str1 string, str2 string) f64 {
s1_len := str1.len
s2_len := str2.len
if s1_len == 0 && s2_len == 0 {
return 1
}
if s1_len == 0 || s2_len == 0 {
return 0
}
match_distance := math.max<int>(s1_len,s2_len)/2 - 1
mut str1_matches := []bool{len: s1_len}
mut str2_matches := []bool{len: s2_len}
mut matches := 0
mut transpositions := 0.0
for i in 0..s1_len {
start := math.max<int>(0,i - match_distance)
end := math.min<int>(i + match_distance, s2_len)
for k in start..end {
if str2_matches[k] {
continue
}
if str1[i] != str2[k] {
continue
}
str1_matches[i] = true
str2_matches[k] = true
matches++
break
}
}
if matches == 0 {
return 0
}
mut k := 0
for i in 0..s1_len {
if !str1_matches[i] {
continue
}
for !str2_matches[k] {
k++
}
if str1[i] != str2[k] {
transpositions++
}
k++
}
transpositions /= 2
return (matches/f64(s1_len) +
matches/f64(s2_len) +
(matches-transpositions)/matches) / 3
}
fn main() {
println(jaro("MARTHA", "MARHTA"))
println(jaro("DIXON", "DICKSONX"))
println(jaro("JELLYFISH", "SMELLYFISH"))
}</syntaxhighlight>
{{out}}
<pre>0.9444444444444445
0.7666666666666666
0.8962962962962964
</pre>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-fmt}}
<langsyntaxhighlight ecmascriptlang="wren">import "./fmt" for Fmt
 
var jaro = Fn.new { |s1, s2|
Line 3,041 ⟶ 3,679:
}
}
transpos = (transpos / 2).floor
return (matches/le1 + matches/le2 + (matches - transpos)/matches) / 3
}
Line 3,047 ⟶ 3,685:
System.print(Fmt.f(0, jaro.call("MARTHA", "MARHTA")))
System.print(Fmt.f(0, jaro.call("DIXON", "DICKSONX")))
System.print(Fmt.f(0, jaro.call("JELLYFISH", "SMELLYFISH")))</langsyntaxhighlight>
 
{{out}}
Line 3,057 ⟶ 3,695:
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl"> //-->String of matched characters, ordered
fcn _jaro(str1,str2, matchDistance){
cs:=Sink(String);
Line 3,077 ⟶ 3,715:
( matches/s1Len + matches/s2Len +
((matches - transpositions)/matches) ) / 3.0
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">foreach s,t in (T(
T("MARTHA","MARHTA"), T("DIXON","DICKSONX"), T("JELLYFISH","SMELLYFISH"))){
println(0'|jaro("%s","%s") = %.10f|.fmt(s,t,jaro(s,t)));
}</langsyntaxhighlight>
{{out}}
<pre>
Line 3,091 ⟶ 3,729:
=={{header|ZX Spectrum Basic}}==
{{trans|FreeBASIC}}
<langsyntaxhighlight lang="zxbasic">10 LET a$="MARTHA": LET b$="MARHTA": PRINT a$;", ";b$;": ";: GO SUB 1000: PRINT jaro
20 LET a$="DIXON": LET b$="DICKSONX": PRINT a$;", ";b$;": ";: GO SUB 1000: PRINT jaro
30 LET a$="JELLYFISH": LET b$="SMELLYFISH": PRINT a$;", ";b$;": ";: GO SUB 1000: PRINT jaro
Line 3,112 ⟶ 3,750:
5000 REM Functions
5010 DEF FN x(a,b)=(a AND a>b)+(b AND a<b)+(a AND a=b): REM max function
5020 DEF FN n(a,b)=(a AND a<b)+(b AND a>b)+(a AND a=b): REM min function</langsyntaxhighlight>
{{out}}
<pre>MARTHA, MARHTA: 0.94444444
337

edits