# Ordering a sequence of objects by type

The below code takes an incoming sequence of objects, checks each object's type and then yields the object in a specific order. This is all taking place in an active pattern. As I am still new to F#, I would like to know if there is a better or more efficient way of accomplishing this task.

    type ArticleObj =
| Submission
| Photos
| ReviewRating
| ArticleTag

let (|OrderArticleObj|_|) (objSeq : seq<obj>) =

// Create DU array
let articleParts = [|
Submission; Photos; ReviewRating;
|]

// create ordered array of objects
let orderedSeq = seq{
for row in articleParts do
for row2 in objSeq do
match row with
| Submission ->
let isValid =
match row2 with
| :? ArticleSubmission as Sub -> true
| _ -> false

if isValid
then
yield row2
| Photos ->
let isValid =
match row2 with
| :? seq<Photos> as Photo -> true
| _ -> false

if isValid
then
yield row2
| ReviewRating ->
let isValid =
match row2 with
| :? ArticleReviewRating as RevRating -> true
| _ -> false

if isValid
then
yield row2
let isValid =
match row2 with
| :? BusinessReviewRating as BizRev -> true
| _ -> false

if isValid
then
yield row2
| ArticleTag ->
let isValid =
match row2 with
| :? seq<ArticleTags> as ArtTag -> true
| _ -> false

if isValid
then
yield row2
}

if not (Seq.isEmpty orderedSeq)
then Some(orderedSeq) else None

• you could indent much less - I would probably have Submission; Photos; ReviewRating;  only indented 8 spaces for example – John Palmer Dec 3 '14 at 22:29

You could define a sorted list of the types and use that to sort the input. Here's what a function that does that would look like.

let sortArticles : seq<obj> -> seq<obj> =
let sorted =
[
typeof<ArticleSubmission>
typeof<seq<Photos>>
typeof<ArticleReviewRating>
typeof<seq<ArticleTags>>
]
Seq.sortBy (fun o -> sorted |> List.findIndex ((=) (o.GetType())))

• I understand the gist of what's going on, but can you explain the purpose of the (=) operator in this context? I haven't seen it used this way before. – user1206480 Dec 4 '14 at 1:32
• Also, are there any errors to handle if a type is not matched? – user1206480 Dec 4 '14 at 1:56
• (=) (o.GetType()) is partially applying the = operator. It's shorthand for fun ty -> ty = o.GetType(). List.findIndex throws an ArgumentException if a matching item is not found. – Daniel Dec 4 '14 at 15:07
• I am now confused the longer I look at this. Doesn't the above inner function return an int as a key for the sortBy function? How would that help me sort a seq<obj> given to the sortBy function? – user1206480 Dec 4 '14 at 15:10
• Right. You can think of the lambda as a "mapping" from input element to key. Or, as the docs explain: Applies a key-generating function to each element of a sequence and yields a sequence ordered by keys – Daniel Dec 4 '14 at 17:31