Joao Saraiva
Joao Saraiva

Reputation: 91

How to find inside a list of lists a list with a single element

I have been trying to do a function that returns to me the first (or all it might work to but I do prefer just the first), element of a list of lists that is single, i mean:

[[x;y;z];[a;b;c];[a];[b]]

In this case I would like to get returned the a or [a] but I cant I tried to do a function something like:

let rec find_unit ll =
  match ll with
  | [x] -> [x]

and so on...

But every time I try something like this, I get in a recursion that never stops, or the function simple dont return the element. Can someone tell me how to do it properly? I still cant understand a lot of OCaml syntax... Just like in the example I dont know that to put in the line of |[x] -> [x], particularly the first [x].

Sorry for the question but I am destroying my code now and I cant find a solution.

Upvotes: 0

Views: 1414

Answers (3)

Joao Saraiva
Joao Saraiva

Reputation: 91

Well all answers here helped me find a way to get the solution, and I am going to put it here because it might help someone else. I used the function:

let is_single xs = function
  | [_] -> true
  | _   -> false

to do: let teste xs = List.filter(fun inner ->(is_single inner)inner)xs;; This teste function is returning to me a List of Lists with all single elements, so to get only one element inside of that lists i did: List.hd(List.hd teste xs)

Upvotes: 0

Anton Trunov
Anton Trunov

Reputation: 15404

Try decomposing your problem into smaller subproblems.

(1) Your problem overall looks like an instance of the more general 'find'-problem, which has already been solved. See the standard function List.find or (if you want to find them all... List.find_all. Both functions need a predicate to pick the right element(s) from the list.

(2) You need a way to determine if some list is a singleton. It's easy, use pattern-mathing.

let is_singleton xs = function
  | [_] -> true
  | _   -> false

(3) Now, combine the above and you'll get a solution.

Upvotes: 3

Jeffrey Scofield
Jeffrey Scofield

Reputation: 66803

A couple of observations on the code you give:

  1. Your pattern needs to match the whole string ll, but the pattern you give seems to be intended to match just one element of ll. A pattern more like [x] :: rest is going to work better.

  2. The way to avoid infinite recursion is always the same. First, make sure you check for the smallest possible input (the basis). For your problem this will be the case when ll is an empty list. Second, if you haven't found what you're looking for, continue the search on a smaller problem. In your case this will mean searching the tail of your list.

You also need to decide what to do when there is no element of the list like the one you're looking for. If you return [x] when you find it, you could return [] (say) if you don't find it. Or you could raise an exception like Not_found.

(As a side comment, lists and arrays are different things in OCaml. I removed the array tag, as your question seems to be about lists.)

Upvotes: 0

Related Questions