rustoption-type

How can I "merge" two options, keeping one if only one exists?


I find myself regularly encountering the need for logic where two optional values should be "merged" where:

This is useful for example when you want to keep the largest or smallest known value. I have not seen a method on Option in the standard library that does this.

This is different from:


Solution

  • This can be done directly with a match:

    match (a_opt, b_opt) {
        (Some(a), Some(b)) => Some(Ord::max(a, b)), // pick the largest
        (Some(a), None) => Some(a),
        (None, Some(b)) => Some(b),
        (None, None) => None,
    }
    

    If I need this more than once I usually create my own function (sometimes as an extention method):

    fn merge<T>(a: Option<T>, b: Option<T>, f: impl FnOnce(T, T) -> T) -> Option<T> {
        match (a, b) {
            (Some(a), Some(b)) => Some(f(a, b)),
            (Some(a), None) => Some(a),
            (None, Some(b)) => Some(b),
            (None, None) => None,
        }
    }
    
    merge(a_opt, b_opt, Ord::max)