# How do I get a specific number of items from a collection containing the repeated items from another collection?

Given a collection of items, how do I return a (possibly repeated) collection containing those individual items, in the order they are given in the original collection, but limited to a specific total number of items?

Apologies for the weird wording of the question but I couldn’t think of a more succinct way of saying it.

This is my first time asking a question in the forums and I’ve still got a lot to learn about F# (again).

With this definition:

``````type Thingy =
| Doodah
| Whatsit
``````

I would like to create a collection (doesn’t need to be a sequence) of items, such as
`let items = seq { Doodah; Whatsit } // Number of items must be at least one.`

With a ‘limiting value’ such as:
`let number = 7 // Could be any integer value greater than zero.`

And then I would like to create a collection (preferably a sequence but doesn’t have to be) which would be as follows:
`{ Doodah; Whatsit; Doodah; Whatsit; Doodah; Whatsit; Doodah } // Note: There’s no ‘Whatsit’ at the end, 7 items only.`
… where the number of items in the resultant collection is the number in the number value.

I’ve managed to cobble together this code:
`let oneByOne items number = seq {for _ in 1..number do yield! items } |> Seq.take number`
… which works, but I think it looks ‘nasty’ (and I’m worried that it could be ‘generating’ more values than it returns, but don’t know how to check).

Is there a better way of doing this?
Is there a ‘shortcut’ version when I know there will only be two items in the original collection?
Is there a particular set of functions that I should be learning more about for this sort of thing?

I’ve done quite a bit of web searching but can’t find anything relevant.

Welcome GarryP!

It’s actually pretty easy to check what values are being generated, by just creating a `seq` that prints on each value:

``````let xs = seq {
for i in 1 .. 2 do
printfn "producing %i" i
yield i
}
``````

then you can see

``````> oneByOne xs 7 |> Seq.toArray;;
producing 1
producing 2
producing 1
producing 2
producing 1
producing 2
producing 1
val it: int[] = [|1; 2; 1; 2; 1; 2; 1|]
``````

So you can see it produced no extra values than it needed. (Note you need to do `Seq.toArray` since the results of `oneByOne` itself is lazy, and converting it to an array forces all of the elements to evaluate).

Personally, I think the way you did it looks really nice, and idiomatic for F# (though it would be a bit more idiomatic to reverse the order of arguments, so you could do `items |> oneByOne 7`).
Maybe it would look nice to make an infinite sequence of repeated elements, since it’s a little funny to go from `1 .. number ` in your `oneByOne` implementation, since that’s a fairly arbitrary upper bound. You could do

``````let cycle xs = seq { for _ in Seq.initInfinite id do yield! xs }
let oneByOne number items = cycle items |> Seq.take number
``````

But there’s no performance difference between that and your implementation, and it’s arguable whether the implementation is “nicer” in any way.

Learning the functions in the `Seq` module is really the only thing that I can think of that would be worth learning for this sort of thing. e.g., in other Functional Programming languages the `cycle` function already exists and that would have simplified the solution, but in this case F# just happened to not have that function pre-defined.

Thanks for the welcome and the advice.

I’ve made the changes to my code and it looks much better now:

``````let cycle originalSequence = seq { for _ in Seq.initInfinite id do yield! originalSequence }
cycle (seq { Doodah ; Whatsit }) |> Seq.take 7
``````

Seq.initInfinite also allowed me to change:

``````let repeatedSingle item numberOfItems = seq {for _ in 1..numberOfItems -> item}
7 |> repeatedSingle Doodah
``````

…into:

``````let endless item = Seq.initInfinite (fun (_) -> item)
endless Doodah |> Seq.take 7
``````

…which, I think, is a lot nicer.

Looks like I’m going to have to read a lot more about Seq.

Cheers.

P.S. I have no idea why the editor in this site has decided to colour some of the code differently to the other code.

1 Like