Let's say I have an array
let arr = [|1;2;3;4;5;6|]
I would like to convert it to something like
[|(1,2);(3,4);(5,6)|]
I've seen Seq.window but this one is going to generate something like
[|(1,2);(2,3);(3,4);(4,5);(5,6)|]
which is not what I want
You can use Array.chunkBySize and then map each sub-array into tuples:
let input = [|1..10|]
Array.chunkBySize 2 list |> Array.map (fun xs -> (xs.[0], xs.[1]))
#Slugart's accepted answer is the best approach (IMO) assuming you know that the array has an even number of elements, but here's another approach that doesn't throw an exception if there does happen to be an odd number (it just omits the last trailing element):
let arr = [|1;2;3;4;5|]
seq { for i in 0 .. 2 .. arr.Length - 2 -> (arr.[i], arr.[i+1]) } |> Seq.toArray
You could use Seq.pairwise, as long as you filter out every other tuple. The filtering needs to pass a state through the iteration, which is usually effected by the scan function.
[|1..10|]
|> Seq.pairwise
|> Seq.scan (fun s t ->
match s with None -> Some t | _ -> None )
None
|> Seq.choose id
|> Seq.toArray
// val it : (int * int) [] = [|(1, 2); (3, 4); (5, 6); (7, 8); (9, 10)|]
But then it's also possible to have scan generate the tuples directly, on penalty of an intermediate array.
[|1..10|]
|> Array.scan (function
| Some x, _ -> fun y -> None, Some(x, y)
| _ -> fun x -> Some x, None )
(None, None)
|> Array.choose snd
Use Seq.pairwise to turn a sequence into tuples
[|1;2;3;4;5;6|]
|> Seq.pairwise
|> Seq.toArray
val it : (int * int) [] = [|(1, 2); (2, 3); (3, 4); (4, 5); (5, 6)|]
Should be:
let rec slice =
function
| [] -> []
| a::b::rest -> (a,b) :: slice (rest)
| _::[] -> failwith "cannot slice uneven list"
Related
Let's say I have this array:
let reportStructure = [|(2, 1); (3, 2); (4, 2); (5, 3); (6, 4); (7, 3)|]
where the first int in a tuple reports to the second int.
I can map that really easily with
let orgMap = Map.ofArray reporting
From there, I could easily get a list of all the ints that report to 2 with
orgMap
|> Map.filter (fun _ key -> key = 2)
which returns
map [(3, 2); (4, 2)]
What I'd really like to see, however, is the entire structure, from 2 all the way down. For example, I'd like to find a way that could give me the sample output
map [(3, 2); (4, 2); (5, 3); (6, 4); (7, 3)]
if I'm looking for person 2 or
map [(5, 3); (7, 3)]
if I'm interested in person 3.
Can I do this? If so, how? Is there another structure other than a map that would be a better way to make this happen?
Thanks in advance for your help.
Since OCaml is close to F# and trying to find Topological sort in F# was not turning up anything useful I looked for OCaml code.
I found An Introduction to Objective Caml which had a solution to your problem using Depth First Search and used it as the basis for this answer. Also because you are new to F# you can review the document and see how the code is derived. Oddly I took a look at the remainder of the document after posting this and he has a more advanced version of DFS latter in the document.
Your input is an array [| |] but your answer is a list [] so I did most of the work as list.
The answers are not in the same order as you had, but they are in the same format.
let reportStructure = [|(2, 1); (3, 2); (4, 2); (5, 3); (6, 4); (7, 3)|]
//
// 6 -> 4 -> 2
// 5 -> 3 -> 2 -> 1
// 7 -> 3
// val revStructure : tl:('a * 'b) list -> ('b * 'a) list
let revStructure tl = List.map (fun (a,b) -> (b,a)) tl
// val mem : item:'a -> list:'a list -> bool when 'a : equality
let mem item list = List.exists (fun x -> x = item) list
// val successors : n:'a -> edges:('a * 'b) list -> 'b list when 'a : equality
let successors n edges =
let matching (s,_) = s = n
List.map snd (List.filter matching edges)
// val dist : pred:'a -> succs:'b list -> ('a * 'b) list
let dist pred succs = List.map (fun y -> (pred,y)) succs
// val dfsPairs : edges:('a * 'a) list -> start:'a -> ('a * 'a) list when 'a : equality
let dfsPairs edges start =
let rec dfsPairsInner edges visited start result =
match start with
| [] -> List.rev (revStructure result)
| n::nodes ->
if mem n visited then
dfsPairsInner edges visited nodes result
else
let predecessors = dist n (successors n edges)
let result =
match predecessors with
| [] -> result
| _ -> predecessors # result
dfsPairsInner edges (n::visited) ((successors n edges) # nodes) result
dfsPairsInner edges [] [start] []
let revEdges = revStructure (List.ofArray reportStructure)
let result = dfsPairs revEdges 2
// val result : (int * int) list = [(4, 2); (3, 2); (7, 3); (5, 3); (6, 4)]
let result = dfsPairs revEdges 3
// val result : (int * int) list = [(7, 3); (5, 3)]
I assume that you want to get a list of pair of ints with "numbers" that directly or indirectly report to some "root".
Here is an easy but inefficient solution:
let reportStructure = [|(2, 1); (3, 2); (4, 2); (5, 3); (6, 4); (7, 3)|]
let reportStructureSet =
reportStructure |> Set.ofArray
let reportingDirectlyTo root raportsToSet =
raportsToSet
|> Set.filter(fun (_, key) -> key = root)
let addNextGeneration previousIteration raportsToSet =
let numbersLowerInHierarchy = previousIteration |> Set.map fst
raportsToSet |> Set.filter(
// select only those elements from raportsToSet...
fun (num, supervisor) ->
// ...which either are already in previousIteration
(Set.contains (num, supervisor) previousIteration) ||
// ...or are "below" someone from previousIteration
(Set.contains supervisor numbersLowerInHierarchy))
let reportingDirectlyOrIndirectlyTo root raportsToSet =
// applies addNextGeneration until is "stabilizes" on some value
let rec fixPointHelper previousIteration =
let nextIteration = addNextGeneration previousIteration raportsToSet
if nextIteration = previousIteration
then nextIteration
else fixPointHelper nextIteration
// set of numbers directly reporting to root
let reportsDirectly = reportingDirectlyTo root raportsToSet
// start "iteration" using numbers directly reporting to root
fixPointHelper reportsDirectly
let reportingDirectlyOrIndirectlyToList root raportsToSet =
reportingDirectlyOrIndirectlyTo root raportsToSet
|> Set.toList
If you want to implement an efficient solution, you should interpret reportStructureSet as a graph in following way:
ints are vertices
pair of ints are directed edges
Then simply check which edges are reachable from "root" using a DFS.
I like f# puzzles, so I took a stab at this one. I hope that you enjoy.
let orgList = [(2, 1); (3, 2); (4, 2); (5, 3); (6, 4); (7, 3)]
let orgMap =
orgList
|> List.fold (fun acc item ->
let key = snd item
match Map.tryFind key acc with
| Some(value) ->
let map' = Map.remove key acc
Map.add(key) (item::value) map'
| None ->
Map.add(key) (item::[]) acc
) Map.empty<int, (int*int) list>
let findReports supervisor =
let rec findReports' acc collection =
match collection with
| head::tail ->
(findReports' (head::acc) tail)
# match Map.tryFind (fst head) orgMap with
| Some(value) -> (findReports' [] value)
| None -> []
| [] -> acc
findReports' [] (Map.find supervisor orgMap)
findReports 2
|> List.map fst
|> List.distinct
returns
val it : int list = [3; 4; 5; 7; 6]
findReports 2 returns
val it : (int * int) list = [(3, 2); (4, 2); (5, 3); (7, 3); (6, 4)]
I'll break it down to clarify.
let orgList = [ (1, 2); (1, 3); (1, 4); (2, 5); (3, 6); (4, 5); (5, 6); (5, 7) ]
We take your list of tuples and create a functional map of boss to ((report,boss) list). This might be known as an adjacency list, which is used for traversing graphs.
let orgMap =
orgList
|> List.fold (fun acc item ->
let key = snd item
match Map.tryFind key acc with
If there is a list of reports under a boss, add to that list.
| Some(reports) ->
let map' = Map.remove key acc
Map.add(key) (item::reports) map'
Otherwise, add to an empty list and insert into the dictionary.
| None ->
Map.add(key) (item::[]) acc
Start with an empty map as an accumulator.
) Map.empty<int, (int*int) list>
Recurse through the items to find all reports.
let findReports supervisor =
let rec findReports' acc collection =
match collection with
If there is an item, append it to the accumulator. This is BFS. If you switch the expression before and after the concatenate operator (#), it will become DFS.
| head::tail ->
(findReports' (head::acc) tail)
Concatenate the current list to the recursive list of reports to reports.
# match Map.tryFind (fst head) orgMap with
| Some(value) -> (findReports' [] value)
| None -> []
If at the end of the list, return the list.
| [] -> acc
Run the recursive function.
findReports' [] (Map.find supervisor orgMap)
Run the function.
findReports 7
Return only the reports
|> List.map fst
Don't report the report twice.
|> List.distinct
I have an integer array in which I want to send every two elements from it to the constructor of another function.
Something like intArray |> Array.map (fun x, y -> new Point(x, y))
Is this possible? I'm new to F# and functional programming so I'm trying to avoid just looping through every 2 items in the array and adding the point to a list. I hope that's reasonable.
If using F# 4.0, use Gustavo's approach. For F# 3, you can do:
intArray
|> Seq.pairwise // get sequence of tuples of element (1,2); (2,3); (3,4); (4,5) etc
|> Seq.mapi (fun i xy -> i, xy) // combine the index with the tuple
|> Seq.filter (fun (i,_) -> i % 2 = 0) // Filter for only the even indices to get (1,2); (3,4)
|> Seq.map (fun xy -> Point xy) // make a point from the tuples
|> Array.ofSeq // convert back to array
You can use Array.chunkBySize:
intArray
|> Array.chunkBySize 2
|> Array.map (function
| [|x; y|] -> new Point (x, y)
| _ -> failwith "Array length is not even.")
An alternative solution to the existing answers, would be to write a custom function, that creates a list/an array of tuples using pattern matching:
let chunkify arr =
let rec chunkify acc lst =
if (List.length lst) > 1 then (* proceed if there are at least two elements *)
match lst with
(* save every constructed pair, until the input is not empty *)
| h1 :: h2 :: tail -> chunkify ([(h1, h2)] # acc) tail
| _ -> acc (* else return the list of pairs *)
else (* return the list of pairs *)
acc
chunkify List.empty (List.ofSeq arr) |> List.rev |> Array.ofSeq
The function can be then used like this:
// helper
let print = (fun (x:'a, y:'a) -> printfn "new Object(%A,%A)" x y)
// ints
[|1;2;3;4;5;6|]
|> chunkify
|> Array.iter print
// strings
[|"a";"b";"c";"d";"e"|]
|> chunkify
|> Array.map print
|> ignore
The output is:
new Object(1,2)
new Object(3,4)
new Object(5,6)
new Object("a","b")
new Object("c","d")
This solution/approach uses pattern matching with lists.
I'm trying to make a custom fold which goes through my sequence, and takes 2 Teams a time and assign them to a Match and then return a Match list in the end.
My current code is:
let myFold f s =
let rec myFold' f s acc =
match s with
| (a1::a2::a) -> f a1 a2::acc
| _ -> acc
myFold' f s []
Which gives me (int -> int) list
But obviously thats not going to work... What am I doing wrong?
-> I know that I just can create a recrusive function special made for this scenario, however I want to make it so abstract as possible for reuse.
Im' not quite sure that I get what you want to achieve. From sequence [1;2;3;4] you want to get [(1,2); (3,4)] or [(1,2); (2,3); (3,4)] ?
let fold f s =
let rec impl acc = function
| x::y::rest -> impl ((f x y)::acc) rest
| _ -> List.rev acc
impl [] s
let s = [1;2;3;4;5;6]
let r = fold (fun x y -> x,y) s // [(1, 2); (3, 4); (5, 6)]
let fold2 f s = Seq.pairwise s |> Seq.map f |> Seq.toList
let r2 = fold2 id s // [(1, 2); (2, 3); (3, 4); (4, 5); (5, 6)]
I have been looking for an elegant way to write a function that takes a list of elements and returns a list of tuples with all the possible pairs of distinct elements, not taking into account order, i.e. (a,b) and (b,a) should be considered the same and only one of them be returned.
I am sure this is a pretty standard algorithm, and it's probably an example from the cover page of the F# documentation, but I can't find it, not even searching the Internet for SML or Caml. What I have come up with is the following:
let test = [1;2;3;4;5;6]
let rec pairs l =
seq {
match l with
| h::t ->
yield! t |> Seq.map (fun elem -> (h, elem))
yield! t |> pairs
| _ -> ()
}
test |> pairs |> Seq.toList |> printfn "%A"
This works and returns the expected result [(1, 2); (1, 3); (1, 4); (1, 5); (1, 6); (2, 3); (2, 4); (2, 5); (2, 6); (3, 4); (3, 5); (3, 6); (4, 5); (4, 6); (5, 6)] but it looks horribly unidiomatic.
I should not need to go through the sequence expression and then convert back into a list, there must be an equivalent solution only involving basic list operations or library calls...
Edited:
I also have this one here
let test = [1;2;3;4;5;6]
let rec pairs2 l =
let rec p h t =
match t with
| hx::tx -> (h, hx)::p h tx
| _ -> []
match l with
| h::t -> p h t # pairs2 t
| _ -> []
test |> pairs2 |> Seq.toList |> printfn "%A"
Also working, but like the first one it seems unnecessarily involved and complicated, given the rather easy problem. I guess my question is mor about style, really, and if someone can come up with a two-liner for this.
I think that your code is actually pretty close to an idiomatic version. The only change I would do is that I would use for in a sequence expression instead of using yield! in conjunction with Seq.map. I also usually format code differently (but that's just a personal preference), so I would write this:
let rec pairs l = seq {
match l with
| h::t -> for e in t do yield h, elem
yield! pairs t
| _ -> () }
This is practically the same thing as what Brian posted. If you wanted to get a list as the result then you could just wrap the whole thing in [ ... ] instead of seq { ... }.
However, this isn't actually all that different - under the cover, the compiler uses a sequence anyway and it just adds conversion to a list. I think that it may be actually a good idea to use sequences until you actually need a list (because sequences are evaluated lazilly, so you may avoid evaluating unnecessary things).
If you wanted to make this a bit simpler by abstracting a part of the behavior into a separate (generally useful) function, then you could write a function e.g. splits that returns all elements of a list together with the rest of the list:
let splits list =
let rec splitsAux acc list =
match list with
| x::xs -> splitsAux ((x, xs)::acc) xs
| _ -> acc |> List.rev
splitsAux [] list
For example splits [ 1 .. 3 ] would give [(1, [2; 3]); (2, [3]); (3, [])]. When you have this function, implementing your original problem becomes much easier - you can just write:
[ for x, xs in splits [ 1 .. 5] do
for y in xs do yield x, y ]
As a guide for googling - the problem is called finding all 2-element combinations from the given set.
Here's one way:
let rec pairs l =
match l with
| [] | [_] -> []
| h :: t ->
[for x in t do
yield h,x
yield! pairs t]
let test = [1;2;3;4;5;6]
printfn "%A" (pairs test)
You seem to be overcomplicating things a lot. Why even use a seq if you want a list? How about
let rec pairs lst =
match lst with
| [] -> []
| h::t -> List.map (fun elem -> (h, elem)) t # pairs t
let _ =
let test = [1;2;3;4;5;6]
printfn "%A" (pairs test)
I been recently playing with F# . I was wondering instead of using a for loop to generate a sequence to element which are multiplied with every other element in the list how can I use a Seq map function or something similar to generate something like below.
So for e.g. I have a list [1..10] I would like to apply a fun which generates a result something like
[(1*1); (1*2);(1*3); (1*4); (1*5)......(2*1);(2*2);(2*3).....(3*1);(3*2)...]
How can i achieve this ?.
Many thanks for all you help.
let list = [1..10]
list |> List.map (fun v1 -> List.map (fun v2 -> (v1*v2)) list) |> List.collect id
The List.collect at the end flattens the list of lists.
It works the same with Seq instead of List, if you want a lazy sequence.
Or, using collect as the main iterator, as cfern suggested and obsessivley eliminating anonymous functions:
let flip f x y = f y x
let list = [1..10]
list |> List.collect ((*) >> ((flip List.map) list))
A list comprehension would be the easiest way to do this:
let allpairs L =
[for x in L do
for y in L -> (x*y)]
Or, without using any loops:
let pairs2 L = L |> List.collect (fun x -> L |> List.map (fun y -> (x*y)))
Edit in response to comment:
You could add a self-crossing extension method to a list like this:
type Microsoft.FSharp.Collections.List<'a> with
member L.cross f =
[for x in L do
for y in L -> f x y]
Example:
> [1;2;3].cross (fun x y -> (x,y));;
val it : (int * int) list =
[(1, 1); (1, 2); (1, 3); (2, 1); (2, 2); (2, 3); (3, 1); (3, 2); (3, 3)]
I wouldn't use an extension method in F# myself, is feels a bit C#'ish. But that's mostly because I don't feel that a fluent syntax is needed in F# because I usually chain my functions together with pipe (|>) operators.
My approach would be to extend the List module with a cross function, not the type itself:
module List =
let cross f L1 L2 =
[for x in L1 do
for y in L2 -> f x y]
If you do this, you can use the cross method like any other method of List:
> List.cross (fun x y -> (x,y)) [1;2;3] [1;2;3];;
val it : (int * int) list =
[(1, 1); (1, 2); (1, 3); (2, 1); (2, 2); (2, 3); (3, 1); (3, 2); (3, 3)]
> List.cross (*) [1;2;3] [1;2;3];;
val it : int list = [1; 2; 3; 2; 4; 6; 3; 6; 9]
Or we can implement a general cross product function:
let cross l1 l2 =
seq { for el1 in l1 do
for el2 in l2 do
yield el1, el2 };;
and use this function to get the job done:
cross [1..10] [1..10] |> Seq.map (fun (a,b) -> a*b) |> Seq.toList
To implement the same thing without for loops, you can use the solution using higher-order functions posted by Mau, or you can write the same thing explicitly using recursion:
let cross xs ys =
let rec crossAux ol2 l1 l2 =
match l1, l2 with
// All elements from the second list were processed
| x::xs, [] -> crossAux ol2 xs ol2
// Report first elements and continue looping after
// removing first element from the second list
| x::xs, y::ys -> (x, y)::(crossAux ol2 l1 ys)
// First list is empty - we're done
| [], _ -> []
crossAux ys xs ys
This may be useful if you're learning functional programming and recursion, however, the solution using sequence expressions is far more practically useful.
As a side-note, the first version by Mau can be made a bit nicer, because you can join the call to List.map with a call to List.collect id like this (you can pass the nested processing lambda directly as a parameter to collect). The cross function would look like this (Of course, you can modifiy this to take a parameter to apply to the two numbers instead of creating a tuple):
let cross xs ys =
xs |> List.collect (fun v1 ->
ys |> List.map (fun v2 -> (v1, v2)))
Incidentally, there is a free chapter from my book avaialable, which discusses how sequence expressions and List.collect functions work. It is worth noting, that for in sequence expressions directly corresponds to List.collect, so you can write the code just by using this higher order function:
let cross xs ys =
xs |> List.collect (fun v1 ->
ys |> List.collect (fun v2 -> [(v1, v2)] ))
However, see the free chapter for more information :-).