Самый простой способ - создать таблицу подстановок из второго и третьего массивов, затем сопоставить каждый элемент первого массива и использовать ее в качестве ключа.
let first = [|"A"; "B"; "C"; "A"; "B"; "A"; "C"; "B"; "C"; "C"; "C"|]
let second = [|"A"; "B"; "C"|]
let third = [|"1"; "2"; "3"|]
let lookupTbl = Map(Array.zip second third) //create a Map/Dictionary from the zipped values
first
|> Array.map (fun x -> lookupTbl.[x]) //Use the first array's values as keys
//val it : string [] = [|"1"; "2"; "3"; "1"; "2"; "1"; "3"; "2"; "3"; "3"; "3"|]
Вы также можете использовать TryFind
, если не уверены, что все ключи существуют, но в вашем случае это не кажется необходимым.
Ваш первоначальный случай не работает, потому что вы пытаетесь использовать if
в качестве оператора, поэтому он возвращает unit
(потому что, если x не равен w).
Если вы хотите остаться ближе к своей исходной структуре, вы можете использовать сопоставление с шаблоном вместо if, а затем удалить несоответствия. Array.collect
сворачивает массив массивов в один массив. Выражение match
делает то же, что и if
в вашем коде, но оно возвращает значение Some
, если есть совпадение, и None
в противном случае. Наконец, мы избавляемся от оболочек None
и Some
Option с помощью Array.choose
.
let rplc (x:string[]) (y:string[]) (z:string[]) =
first
|> Array.collect (fun w ->
Array.map2 (fun x y ->
match (w = x) with
| true -> Some(y)
| _ -> None ) second third)
|> Array.choose id
let fourth =
rplc first second third
printfn ""
printfn "fourth: %A" fourth
// val fourth : string [] =
// [|"1"; "2"; "3"; "1"; "2"; "1"; "3"; "2"; "3"; "3"; "3"|]
// val it : unit = ()