Можете ли вы передать аргументы методу в `& amp; method (: method_ name)` в ruby? [Дубликат]

Вот функция , которую я написал для этой общей задачи. Это более эффективно, чем методы Series / stack. Колонка и имена сохраняются.

def tidy_split(df, column, sep='|', keep=False):
    """
    Split the values of a column and expand so the new DataFrame has one split
    value per row. Filters rows where the column is missing.

    Params
    ------
    df : pandas.DataFrame
        dataframe with the column to split and expand
    column : str
        the column to split and expand
    sep : str
        the string used to split the column's values
    keep : bool
        whether to retain the presplit value as it's own row

    Returns
    -------
    pandas.DataFrame
        Returns a dataframe with the same columns as `df`.
    """
    indexes = list()
    new_values = list()
    df = df.dropna(subset=[column])
    for i, presplit in enumerate(df[column].astype(str)):
        values = presplit.split(sep)
        if keep and len(values) > 1:
            indexes.append(i)
            new_values.append(presplit)
        for value in values:
            indexes.append(i)
            new_values.append(value)
    new_df = df.iloc[indexes, :].copy()
    new_df[column] = new_values
    return new_df

С помощью этой функции исходный вопрос прост как:

tidy_split(a, 'var1', sep=',')

17
задан trh178 9 January 2012 в 20:55
поделиться

1 ответ

К сожалению, эта сокращенная нотация (которая вызывает «Символ # to_proc») не имеет способа передать аргументы вызываемому методу или блоку, поэтому вы даже не можете сделать следующее:

array_of_strings.map(&:include, 'l') #=> this would fail

НО, вам повезло, потому что вам действительно не нужен этот ярлык , чтобы делать то, что вы пытаетесь сделать. Амперсанд может преобразовать Proc или Lambda в блок, и наоборот:

my_routine = Proc.new { |str| str.upcase }
%w{ one two three }.map &my_routine #=> ['ONE', 'TWO', 'THREE']

Обратите внимание на отсутствие двоеточия до my_routine. Это связано с тем, что мы не хотим преобразовать символ :my_routine в proc, найдя метод и вызывая .method на нем, вместо этого мы хотим преобразовать my_routine Proc в блок и передать его в map .

Зная это, вы даже можете сопоставить собственный метод Ruby:

%w{ one two three }.map &method(:p)

Метод method будет принимать метод p и преобразовывать его в Proc, и & преобразует его в блок, который передается в map. В результате каждый элемент печатается. Это эквивалентно этому:

%w{ one two three }.map { |s| p s }
37
ответ дан coreyward 28 August 2018 в 09:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: