from typing import OrderedDict


def groupby(items, by):
    """
    Group items using a function to derive a key.

    :param items:
        The items to group

    :param by:
        A lambda function to create a key based on the item

    :return:
        an Ordered dict
    """
    result = OrderedDict()
    for item in items:
        key = by(item)

        if key in result:
            result[key].append(item)
        else:
            result[key] = [item]

    return result