Promixity in collection
Original Question
I want to use F# to find the proximity of consonants to vowels in a collection of words. So for example in the word "top" T is (-1: 1) from a vowel and P is (1: 1) from the vowel.
The first number in the pair is the position and the second number is the number of times it's in that position, relative to the nearest vowel.
In "consonants", C is (-1:1), N is (1: 3) , (-2: 1), (-1, 1), S is (2: 1), (-1:1),(3: 1) and T is (2: 1).
I suspect that I have to use a combination of groupBy, findIndex and countBy.
type ConsonantPos = { Name: string
BeforeVowel: int
AfterVowel: int }
let isVowel (x:string) =
List.contains x ["a";"e"; "i"; "o"; "u"]
let consonantPosVsVowel x lst =
let rec getConsonanatPos x beforeVowel afterVowel currentPos lst =
match lst with
| -> {Name = x; BeforeVowel = beforeVowel; AfterVowel = afterVowel}
| h::t ->
if isVowel h then
{Name = x; BeforeVowel = beforeVowel; AfterVowel = afterVowel}
else
getConsonanatPos x (beforeVowel - 1) (afterVowel + 1) (currentPos + 1) t
getConsonanatPos x 0 0 0 lst
["b"; "a"; "c"] |> consonantPosVsVowel "b"
// val it : ConsonantPos = {Name = "b"; BeforeVowel = -1; AfterVowel = 1;}
["b"; "c"; "d"; "e"; "f"; "g"] |> consonantPosVsVowel "b"
// val it : ConsonantPos = {Name = "b"; BeforeVowel = -3; AfterVowel = 3;}
Revised Solution
As of 21/11/2018 both suggestions worked and worked well for the problem as I orginally specified.
Of course this question was just a part of the program that I was writing. As I have extended the program and explored the data, BEEP, one response proved easier to reuse: that is the one I have marked as the answer.
My problem, as it turned out, was my lack of understanding of and my inability to use collections.
f#
add a comment |
Original Question
I want to use F# to find the proximity of consonants to vowels in a collection of words. So for example in the word "top" T is (-1: 1) from a vowel and P is (1: 1) from the vowel.
The first number in the pair is the position and the second number is the number of times it's in that position, relative to the nearest vowel.
In "consonants", C is (-1:1), N is (1: 3) , (-2: 1), (-1, 1), S is (2: 1), (-1:1),(3: 1) and T is (2: 1).
I suspect that I have to use a combination of groupBy, findIndex and countBy.
type ConsonantPos = { Name: string
BeforeVowel: int
AfterVowel: int }
let isVowel (x:string) =
List.contains x ["a";"e"; "i"; "o"; "u"]
let consonantPosVsVowel x lst =
let rec getConsonanatPos x beforeVowel afterVowel currentPos lst =
match lst with
| -> {Name = x; BeforeVowel = beforeVowel; AfterVowel = afterVowel}
| h::t ->
if isVowel h then
{Name = x; BeforeVowel = beforeVowel; AfterVowel = afterVowel}
else
getConsonanatPos x (beforeVowel - 1) (afterVowel + 1) (currentPos + 1) t
getConsonanatPos x 0 0 0 lst
["b"; "a"; "c"] |> consonantPosVsVowel "b"
// val it : ConsonantPos = {Name = "b"; BeforeVowel = -1; AfterVowel = 1;}
["b"; "c"; "d"; "e"; "f"; "g"] |> consonantPosVsVowel "b"
// val it : ConsonantPos = {Name = "b"; BeforeVowel = -3; AfterVowel = 3;}
Revised Solution
As of 21/11/2018 both suggestions worked and worked well for the problem as I orginally specified.
Of course this question was just a part of the program that I was writing. As I have extended the program and explored the data, BEEP, one response proved easier to reuse: that is the one I have marked as the answer.
My problem, as it turned out, was my lack of understanding of and my inability to use collections.
f#
Can you show us what you've tried already?
– Ciaran_McCarthy
Nov 19 '18 at 19:46
I am trying things as I go. I hope that I'll work it out.
– Jack Chidley
Nov 19 '18 at 20:07
In your edit Revised Solution, you did change the rules somewhat, so that they do not really match the Original Question any more. You are now also determining the distance of consonants to word boundaries. But this is fine, I'm happy that you found whatever was needed to float your boat.
– kaefer
Nov 20 '18 at 18:21
When I started looking at the problem, I had no idea where to start. As you stated, my actual needs turned out to be slightly different from what I wrote in the question. That is why I left the original question unchanged. Thanks to you, kaefer, and AMieres not only did I manage to solve my real problem but I also learnt a lot. Before I posted the question I had tried, for several hours, to find a solution. It's astonishing to me that two people worked out, and coded, a solution to my original problem in under an hour from posting it! I am so grateful: I love the Stack community
– Jack Chidley
Nov 21 '18 at 7:13
add a comment |
Original Question
I want to use F# to find the proximity of consonants to vowels in a collection of words. So for example in the word "top" T is (-1: 1) from a vowel and P is (1: 1) from the vowel.
The first number in the pair is the position and the second number is the number of times it's in that position, relative to the nearest vowel.
In "consonants", C is (-1:1), N is (1: 3) , (-2: 1), (-1, 1), S is (2: 1), (-1:1),(3: 1) and T is (2: 1).
I suspect that I have to use a combination of groupBy, findIndex and countBy.
type ConsonantPos = { Name: string
BeforeVowel: int
AfterVowel: int }
let isVowel (x:string) =
List.contains x ["a";"e"; "i"; "o"; "u"]
let consonantPosVsVowel x lst =
let rec getConsonanatPos x beforeVowel afterVowel currentPos lst =
match lst with
| -> {Name = x; BeforeVowel = beforeVowel; AfterVowel = afterVowel}
| h::t ->
if isVowel h then
{Name = x; BeforeVowel = beforeVowel; AfterVowel = afterVowel}
else
getConsonanatPos x (beforeVowel - 1) (afterVowel + 1) (currentPos + 1) t
getConsonanatPos x 0 0 0 lst
["b"; "a"; "c"] |> consonantPosVsVowel "b"
// val it : ConsonantPos = {Name = "b"; BeforeVowel = -1; AfterVowel = 1;}
["b"; "c"; "d"; "e"; "f"; "g"] |> consonantPosVsVowel "b"
// val it : ConsonantPos = {Name = "b"; BeforeVowel = -3; AfterVowel = 3;}
Revised Solution
As of 21/11/2018 both suggestions worked and worked well for the problem as I orginally specified.
Of course this question was just a part of the program that I was writing. As I have extended the program and explored the data, BEEP, one response proved easier to reuse: that is the one I have marked as the answer.
My problem, as it turned out, was my lack of understanding of and my inability to use collections.
f#
Original Question
I want to use F# to find the proximity of consonants to vowels in a collection of words. So for example in the word "top" T is (-1: 1) from a vowel and P is (1: 1) from the vowel.
The first number in the pair is the position and the second number is the number of times it's in that position, relative to the nearest vowel.
In "consonants", C is (-1:1), N is (1: 3) , (-2: 1), (-1, 1), S is (2: 1), (-1:1),(3: 1) and T is (2: 1).
I suspect that I have to use a combination of groupBy, findIndex and countBy.
type ConsonantPos = { Name: string
BeforeVowel: int
AfterVowel: int }
let isVowel (x:string) =
List.contains x ["a";"e"; "i"; "o"; "u"]
let consonantPosVsVowel x lst =
let rec getConsonanatPos x beforeVowel afterVowel currentPos lst =
match lst with
| -> {Name = x; BeforeVowel = beforeVowel; AfterVowel = afterVowel}
| h::t ->
if isVowel h then
{Name = x; BeforeVowel = beforeVowel; AfterVowel = afterVowel}
else
getConsonanatPos x (beforeVowel - 1) (afterVowel + 1) (currentPos + 1) t
getConsonanatPos x 0 0 0 lst
["b"; "a"; "c"] |> consonantPosVsVowel "b"
// val it : ConsonantPos = {Name = "b"; BeforeVowel = -1; AfterVowel = 1;}
["b"; "c"; "d"; "e"; "f"; "g"] |> consonantPosVsVowel "b"
// val it : ConsonantPos = {Name = "b"; BeforeVowel = -3; AfterVowel = 3;}
Revised Solution
As of 21/11/2018 both suggestions worked and worked well for the problem as I orginally specified.
Of course this question was just a part of the program that I was writing. As I have extended the program and explored the data, BEEP, one response proved easier to reuse: that is the one I have marked as the answer.
My problem, as it turned out, was my lack of understanding of and my inability to use collections.
f#
f#
edited Nov 21 '18 at 11:06
Jack Chidley
asked Nov 19 '18 at 19:12
Jack ChidleyJack Chidley
699
699
Can you show us what you've tried already?
– Ciaran_McCarthy
Nov 19 '18 at 19:46
I am trying things as I go. I hope that I'll work it out.
– Jack Chidley
Nov 19 '18 at 20:07
In your edit Revised Solution, you did change the rules somewhat, so that they do not really match the Original Question any more. You are now also determining the distance of consonants to word boundaries. But this is fine, I'm happy that you found whatever was needed to float your boat.
– kaefer
Nov 20 '18 at 18:21
When I started looking at the problem, I had no idea where to start. As you stated, my actual needs turned out to be slightly different from what I wrote in the question. That is why I left the original question unchanged. Thanks to you, kaefer, and AMieres not only did I manage to solve my real problem but I also learnt a lot. Before I posted the question I had tried, for several hours, to find a solution. It's astonishing to me that two people worked out, and coded, a solution to my original problem in under an hour from posting it! I am so grateful: I love the Stack community
– Jack Chidley
Nov 21 '18 at 7:13
add a comment |
Can you show us what you've tried already?
– Ciaran_McCarthy
Nov 19 '18 at 19:46
I am trying things as I go. I hope that I'll work it out.
– Jack Chidley
Nov 19 '18 at 20:07
In your edit Revised Solution, you did change the rules somewhat, so that they do not really match the Original Question any more. You are now also determining the distance of consonants to word boundaries. But this is fine, I'm happy that you found whatever was needed to float your boat.
– kaefer
Nov 20 '18 at 18:21
When I started looking at the problem, I had no idea where to start. As you stated, my actual needs turned out to be slightly different from what I wrote in the question. That is why I left the original question unchanged. Thanks to you, kaefer, and AMieres not only did I manage to solve my real problem but I also learnt a lot. Before I posted the question I had tried, for several hours, to find a solution. It's astonishing to me that two people worked out, and coded, a solution to my original problem in under an hour from posting it! I am so grateful: I love the Stack community
– Jack Chidley
Nov 21 '18 at 7:13
Can you show us what you've tried already?
– Ciaran_McCarthy
Nov 19 '18 at 19:46
Can you show us what you've tried already?
– Ciaran_McCarthy
Nov 19 '18 at 19:46
I am trying things as I go. I hope that I'll work it out.
– Jack Chidley
Nov 19 '18 at 20:07
I am trying things as I go. I hope that I'll work it out.
– Jack Chidley
Nov 19 '18 at 20:07
In your edit Revised Solution, you did change the rules somewhat, so that they do not really match the Original Question any more. You are now also determining the distance of consonants to word boundaries. But this is fine, I'm happy that you found whatever was needed to float your boat.
– kaefer
Nov 20 '18 at 18:21
In your edit Revised Solution, you did change the rules somewhat, so that they do not really match the Original Question any more. You are now also determining the distance of consonants to word boundaries. But this is fine, I'm happy that you found whatever was needed to float your boat.
– kaefer
Nov 20 '18 at 18:21
When I started looking at the problem, I had no idea where to start. As you stated, my actual needs turned out to be slightly different from what I wrote in the question. That is why I left the original question unchanged. Thanks to you, kaefer, and AMieres not only did I manage to solve my real problem but I also learnt a lot. Before I posted the question I had tried, for several hours, to find a solution. It's astonishing to me that two people worked out, and coded, a solution to my original problem in under an hour from posting it! I am so grateful: I love the Stack community
– Jack Chidley
Nov 21 '18 at 7:13
When I started looking at the problem, I had no idea where to start. As you stated, my actual needs turned out to be slightly different from what I wrote in the question. That is why I left the original question unchanged. Thanks to you, kaefer, and AMieres not only did I manage to solve my real problem but I also learnt a lot. Before I posted the question I had tried, for several hours, to find a solution. It's astonishing to me that two people worked out, and coded, a solution to my original problem in under an hour from posting it! I am so grateful: I love the Stack community
– Jack Chidley
Nov 21 '18 at 7:13
add a comment |
2 Answers
2
active
oldest
votes
Here's a slightly different approach, which breaks down the task differently.
- Map the element to itself with its tail (negative distance, forward) and heads
(positive, backward). This is done with a recursive function and two
accumulators - Filter the resulting list for elements not being vowels
- Map it to pairs of options representing negative and positive distances, with
another recursive function, and collect these pairs into a flat list
again while transposing their values - Group this list by the elements, and map the result to a tuple of distance and number of occurance
let genTail2 xss =
let rec aux accl accr = function
| -> List.rev accr
| x::xs -> aux (x::accl) ((x, (xs, accl))::accr) xs
aux xss
// val genTail2 : xss:'a list -> ('a * ('a list * 'a list)) list
let dist2 pred (x, (ls, rs)) =
let rec aux n i = function
| -> None
| y::ys -> if pred y then Some(x, n) else aux (n + i) i ys
aux -1 -1 ls, aux 1 1 rs
// val dist2 :
// pred:('a -> bool) ->
// x:'b * ('a list * 'a list) -> ('b * int) option * ('b * int) option
let tuple2List = function
| None, None ->
| Some x, None | None, Some x -> [x]
| Some x, Some y -> [y; x]
// val tuple2List : 'a option * 'a option -> 'a list
let isVowel = ResizeArray['a';'e';'i';'o';'u'].Contains
// val isVowel : (char -> bool)
"consonants"
|> fun s -> s.ToLower()
|> Seq.toList
|> genTail2
|> List.filter (fst >> isVowel >> not)
|> List.collect (dist2 isVowel >> tuple2List)
|> Seq.groupBy fst
|> Seq.map (fun (x, xs) -> x, Seq.countBy snd xs)
|> Seq.iter (printfn "%A")
Wow, this looks like it works too! I am not surprised that I couldn't figure it out myself.
– Jack Chidley
Nov 19 '18 at 22:40
This response proved to be the flexible, easy to understand and easy to reuse.
– Jack Chidley
Nov 21 '18 at 11:14
add a comment |
Try this:
let isVowel (x:char) =
List.contains x ['a';'e'; 'i'; 'o'; 'u']
let countConsonants (word:string) =
let vowelsp, consonants =
word
|> Seq.mapi(fun i c-> c,i )
|> Seq.toArray
|> Array.partition (fst >> isVowel)
let vowels = vowelsp |> Array.map snd
consonants
|> Seq.collect (fun (c,i) ->
match vowels |> Array.tryFindIndex ((<) i) with
| None -> [ vowels.Length - 1 ]
| Some j -> [ j - 1 ; j ]
|> Seq.choose (fun j ->
if j < 0 then None else
Some(c, i - vowels.[j])
)
)
|> Seq.countBy id
|> Seq.map (fun ((l,p), c) -> (l,(p, c)) )
|> Seq.groupBy fst
|> Seq.map (fun (l, s) -> l, s |> Seq.map snd |> Seq.toArray)
|> Seq.toArray
"consonants"
|> countConsonants
|> Seq.iter (printfn "%A")
Oh, that looks like it might work! I need to check it out and watch a film with the wife... could be a while
– Jack Chidley
Nov 19 '18 at 20:48
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53381162%2fpromixity-in-collection%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Here's a slightly different approach, which breaks down the task differently.
- Map the element to itself with its tail (negative distance, forward) and heads
(positive, backward). This is done with a recursive function and two
accumulators - Filter the resulting list for elements not being vowels
- Map it to pairs of options representing negative and positive distances, with
another recursive function, and collect these pairs into a flat list
again while transposing their values - Group this list by the elements, and map the result to a tuple of distance and number of occurance
let genTail2 xss =
let rec aux accl accr = function
| -> List.rev accr
| x::xs -> aux (x::accl) ((x, (xs, accl))::accr) xs
aux xss
// val genTail2 : xss:'a list -> ('a * ('a list * 'a list)) list
let dist2 pred (x, (ls, rs)) =
let rec aux n i = function
| -> None
| y::ys -> if pred y then Some(x, n) else aux (n + i) i ys
aux -1 -1 ls, aux 1 1 rs
// val dist2 :
// pred:('a -> bool) ->
// x:'b * ('a list * 'a list) -> ('b * int) option * ('b * int) option
let tuple2List = function
| None, None ->
| Some x, None | None, Some x -> [x]
| Some x, Some y -> [y; x]
// val tuple2List : 'a option * 'a option -> 'a list
let isVowel = ResizeArray['a';'e';'i';'o';'u'].Contains
// val isVowel : (char -> bool)
"consonants"
|> fun s -> s.ToLower()
|> Seq.toList
|> genTail2
|> List.filter (fst >> isVowel >> not)
|> List.collect (dist2 isVowel >> tuple2List)
|> Seq.groupBy fst
|> Seq.map (fun (x, xs) -> x, Seq.countBy snd xs)
|> Seq.iter (printfn "%A")
Wow, this looks like it works too! I am not surprised that I couldn't figure it out myself.
– Jack Chidley
Nov 19 '18 at 22:40
This response proved to be the flexible, easy to understand and easy to reuse.
– Jack Chidley
Nov 21 '18 at 11:14
add a comment |
Here's a slightly different approach, which breaks down the task differently.
- Map the element to itself with its tail (negative distance, forward) and heads
(positive, backward). This is done with a recursive function and two
accumulators - Filter the resulting list for elements not being vowels
- Map it to pairs of options representing negative and positive distances, with
another recursive function, and collect these pairs into a flat list
again while transposing their values - Group this list by the elements, and map the result to a tuple of distance and number of occurance
let genTail2 xss =
let rec aux accl accr = function
| -> List.rev accr
| x::xs -> aux (x::accl) ((x, (xs, accl))::accr) xs
aux xss
// val genTail2 : xss:'a list -> ('a * ('a list * 'a list)) list
let dist2 pred (x, (ls, rs)) =
let rec aux n i = function
| -> None
| y::ys -> if pred y then Some(x, n) else aux (n + i) i ys
aux -1 -1 ls, aux 1 1 rs
// val dist2 :
// pred:('a -> bool) ->
// x:'b * ('a list * 'a list) -> ('b * int) option * ('b * int) option
let tuple2List = function
| None, None ->
| Some x, None | None, Some x -> [x]
| Some x, Some y -> [y; x]
// val tuple2List : 'a option * 'a option -> 'a list
let isVowel = ResizeArray['a';'e';'i';'o';'u'].Contains
// val isVowel : (char -> bool)
"consonants"
|> fun s -> s.ToLower()
|> Seq.toList
|> genTail2
|> List.filter (fst >> isVowel >> not)
|> List.collect (dist2 isVowel >> tuple2List)
|> Seq.groupBy fst
|> Seq.map (fun (x, xs) -> x, Seq.countBy snd xs)
|> Seq.iter (printfn "%A")
Wow, this looks like it works too! I am not surprised that I couldn't figure it out myself.
– Jack Chidley
Nov 19 '18 at 22:40
This response proved to be the flexible, easy to understand and easy to reuse.
– Jack Chidley
Nov 21 '18 at 11:14
add a comment |
Here's a slightly different approach, which breaks down the task differently.
- Map the element to itself with its tail (negative distance, forward) and heads
(positive, backward). This is done with a recursive function and two
accumulators - Filter the resulting list for elements not being vowels
- Map it to pairs of options representing negative and positive distances, with
another recursive function, and collect these pairs into a flat list
again while transposing their values - Group this list by the elements, and map the result to a tuple of distance and number of occurance
let genTail2 xss =
let rec aux accl accr = function
| -> List.rev accr
| x::xs -> aux (x::accl) ((x, (xs, accl))::accr) xs
aux xss
// val genTail2 : xss:'a list -> ('a * ('a list * 'a list)) list
let dist2 pred (x, (ls, rs)) =
let rec aux n i = function
| -> None
| y::ys -> if pred y then Some(x, n) else aux (n + i) i ys
aux -1 -1 ls, aux 1 1 rs
// val dist2 :
// pred:('a -> bool) ->
// x:'b * ('a list * 'a list) -> ('b * int) option * ('b * int) option
let tuple2List = function
| None, None ->
| Some x, None | None, Some x -> [x]
| Some x, Some y -> [y; x]
// val tuple2List : 'a option * 'a option -> 'a list
let isVowel = ResizeArray['a';'e';'i';'o';'u'].Contains
// val isVowel : (char -> bool)
"consonants"
|> fun s -> s.ToLower()
|> Seq.toList
|> genTail2
|> List.filter (fst >> isVowel >> not)
|> List.collect (dist2 isVowel >> tuple2List)
|> Seq.groupBy fst
|> Seq.map (fun (x, xs) -> x, Seq.countBy snd xs)
|> Seq.iter (printfn "%A")
Here's a slightly different approach, which breaks down the task differently.
- Map the element to itself with its tail (negative distance, forward) and heads
(positive, backward). This is done with a recursive function and two
accumulators - Filter the resulting list for elements not being vowels
- Map it to pairs of options representing negative and positive distances, with
another recursive function, and collect these pairs into a flat list
again while transposing their values - Group this list by the elements, and map the result to a tuple of distance and number of occurance
let genTail2 xss =
let rec aux accl accr = function
| -> List.rev accr
| x::xs -> aux (x::accl) ((x, (xs, accl))::accr) xs
aux xss
// val genTail2 : xss:'a list -> ('a * ('a list * 'a list)) list
let dist2 pred (x, (ls, rs)) =
let rec aux n i = function
| -> None
| y::ys -> if pred y then Some(x, n) else aux (n + i) i ys
aux -1 -1 ls, aux 1 1 rs
// val dist2 :
// pred:('a -> bool) ->
// x:'b * ('a list * 'a list) -> ('b * int) option * ('b * int) option
let tuple2List = function
| None, None ->
| Some x, None | None, Some x -> [x]
| Some x, Some y -> [y; x]
// val tuple2List : 'a option * 'a option -> 'a list
let isVowel = ResizeArray['a';'e';'i';'o';'u'].Contains
// val isVowel : (char -> bool)
"consonants"
|> fun s -> s.ToLower()
|> Seq.toList
|> genTail2
|> List.filter (fst >> isVowel >> not)
|> List.collect (dist2 isVowel >> tuple2List)
|> Seq.groupBy fst
|> Seq.map (fun (x, xs) -> x, Seq.countBy snd xs)
|> Seq.iter (printfn "%A")
edited Nov 19 '18 at 21:56
answered Nov 19 '18 at 21:44
kaeferkaefer
3,4051715
3,4051715
Wow, this looks like it works too! I am not surprised that I couldn't figure it out myself.
– Jack Chidley
Nov 19 '18 at 22:40
This response proved to be the flexible, easy to understand and easy to reuse.
– Jack Chidley
Nov 21 '18 at 11:14
add a comment |
Wow, this looks like it works too! I am not surprised that I couldn't figure it out myself.
– Jack Chidley
Nov 19 '18 at 22:40
This response proved to be the flexible, easy to understand and easy to reuse.
– Jack Chidley
Nov 21 '18 at 11:14
Wow, this looks like it works too! I am not surprised that I couldn't figure it out myself.
– Jack Chidley
Nov 19 '18 at 22:40
Wow, this looks like it works too! I am not surprised that I couldn't figure it out myself.
– Jack Chidley
Nov 19 '18 at 22:40
This response proved to be the flexible, easy to understand and easy to reuse.
– Jack Chidley
Nov 21 '18 at 11:14
This response proved to be the flexible, easy to understand and easy to reuse.
– Jack Chidley
Nov 21 '18 at 11:14
add a comment |
Try this:
let isVowel (x:char) =
List.contains x ['a';'e'; 'i'; 'o'; 'u']
let countConsonants (word:string) =
let vowelsp, consonants =
word
|> Seq.mapi(fun i c-> c,i )
|> Seq.toArray
|> Array.partition (fst >> isVowel)
let vowels = vowelsp |> Array.map snd
consonants
|> Seq.collect (fun (c,i) ->
match vowels |> Array.tryFindIndex ((<) i) with
| None -> [ vowels.Length - 1 ]
| Some j -> [ j - 1 ; j ]
|> Seq.choose (fun j ->
if j < 0 then None else
Some(c, i - vowels.[j])
)
)
|> Seq.countBy id
|> Seq.map (fun ((l,p), c) -> (l,(p, c)) )
|> Seq.groupBy fst
|> Seq.map (fun (l, s) -> l, s |> Seq.map snd |> Seq.toArray)
|> Seq.toArray
"consonants"
|> countConsonants
|> Seq.iter (printfn "%A")
Oh, that looks like it might work! I need to check it out and watch a film with the wife... could be a while
– Jack Chidley
Nov 19 '18 at 20:48
add a comment |
Try this:
let isVowel (x:char) =
List.contains x ['a';'e'; 'i'; 'o'; 'u']
let countConsonants (word:string) =
let vowelsp, consonants =
word
|> Seq.mapi(fun i c-> c,i )
|> Seq.toArray
|> Array.partition (fst >> isVowel)
let vowels = vowelsp |> Array.map snd
consonants
|> Seq.collect (fun (c,i) ->
match vowels |> Array.tryFindIndex ((<) i) with
| None -> [ vowels.Length - 1 ]
| Some j -> [ j - 1 ; j ]
|> Seq.choose (fun j ->
if j < 0 then None else
Some(c, i - vowels.[j])
)
)
|> Seq.countBy id
|> Seq.map (fun ((l,p), c) -> (l,(p, c)) )
|> Seq.groupBy fst
|> Seq.map (fun (l, s) -> l, s |> Seq.map snd |> Seq.toArray)
|> Seq.toArray
"consonants"
|> countConsonants
|> Seq.iter (printfn "%A")
Oh, that looks like it might work! I need to check it out and watch a film with the wife... could be a while
– Jack Chidley
Nov 19 '18 at 20:48
add a comment |
Try this:
let isVowel (x:char) =
List.contains x ['a';'e'; 'i'; 'o'; 'u']
let countConsonants (word:string) =
let vowelsp, consonants =
word
|> Seq.mapi(fun i c-> c,i )
|> Seq.toArray
|> Array.partition (fst >> isVowel)
let vowels = vowelsp |> Array.map snd
consonants
|> Seq.collect (fun (c,i) ->
match vowels |> Array.tryFindIndex ((<) i) with
| None -> [ vowels.Length - 1 ]
| Some j -> [ j - 1 ; j ]
|> Seq.choose (fun j ->
if j < 0 then None else
Some(c, i - vowels.[j])
)
)
|> Seq.countBy id
|> Seq.map (fun ((l,p), c) -> (l,(p, c)) )
|> Seq.groupBy fst
|> Seq.map (fun (l, s) -> l, s |> Seq.map snd |> Seq.toArray)
|> Seq.toArray
"consonants"
|> countConsonants
|> Seq.iter (printfn "%A")
Try this:
let isVowel (x:char) =
List.contains x ['a';'e'; 'i'; 'o'; 'u']
let countConsonants (word:string) =
let vowelsp, consonants =
word
|> Seq.mapi(fun i c-> c,i )
|> Seq.toArray
|> Array.partition (fst >> isVowel)
let vowels = vowelsp |> Array.map snd
consonants
|> Seq.collect (fun (c,i) ->
match vowels |> Array.tryFindIndex ((<) i) with
| None -> [ vowels.Length - 1 ]
| Some j -> [ j - 1 ; j ]
|> Seq.choose (fun j ->
if j < 0 then None else
Some(c, i - vowels.[j])
)
)
|> Seq.countBy id
|> Seq.map (fun ((l,p), c) -> (l,(p, c)) )
|> Seq.groupBy fst
|> Seq.map (fun (l, s) -> l, s |> Seq.map snd |> Seq.toArray)
|> Seq.toArray
"consonants"
|> countConsonants
|> Seq.iter (printfn "%A")
edited Nov 19 '18 at 20:59
answered Nov 19 '18 at 20:41
AMieresAMieres
2,9201611
2,9201611
Oh, that looks like it might work! I need to check it out and watch a film with the wife... could be a while
– Jack Chidley
Nov 19 '18 at 20:48
add a comment |
Oh, that looks like it might work! I need to check it out and watch a film with the wife... could be a while
– Jack Chidley
Nov 19 '18 at 20:48
Oh, that looks like it might work! I need to check it out and watch a film with the wife... could be a while
– Jack Chidley
Nov 19 '18 at 20:48
Oh, that looks like it might work! I need to check it out and watch a film with the wife... could be a while
– Jack Chidley
Nov 19 '18 at 20:48
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53381162%2fpromixity-in-collection%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
Can you show us what you've tried already?
– Ciaran_McCarthy
Nov 19 '18 at 19:46
I am trying things as I go. I hope that I'll work it out.
– Jack Chidley
Nov 19 '18 at 20:07
In your edit Revised Solution, you did change the rules somewhat, so that they do not really match the Original Question any more. You are now also determining the distance of consonants to word boundaries. But this is fine, I'm happy that you found whatever was needed to float your boat.
– kaefer
Nov 20 '18 at 18:21
When I started looking at the problem, I had no idea where to start. As you stated, my actual needs turned out to be slightly different from what I wrote in the question. That is why I left the original question unchanged. Thanks to you, kaefer, and AMieres not only did I manage to solve my real problem but I also learnt a lot. Before I posted the question I had tried, for several hours, to find a solution. It's astonishing to me that two people worked out, and coded, a solution to my original problem in under an hour from posting it! I am so grateful: I love the Stack community
– Jack Chidley
Nov 21 '18 at 7:13