Как выполнить анонимную функцию в параметрах другой функции, чтобы заполнить один из ее параметров? - PullRequest
0 голосов
/ 19 сентября 2018

Итак, у меня есть этот код на C #:

static void Main(string[] args)
{            
   string @string = "- hello dude! - oh hell yeah hey what's up guy";

   Console.WriteLine(String.Join(".", @string.GetSubstringsIndexes("he")));
   Console.Read();
}

частичный класс, который добавляет метод расширения GetSubstringsIndexes:

partial class StringExtension
{
    public static int[] GetSubstringsIndexes(this string @string, string substring)
    {
        List<int> indexes = new List<int>(@string.Length / substring.Length);

        int result = @string.IndexOf(substring, 0);
        while (result >= 0)
        {
            indexes.Add(result);
            result = @string.IndexOf(substring, result + substring.Length);
        }

        return indexes.ToArray();
    }
}

То, что я хотел бы, чтобы это было,лямбда-выражение в скобках параметров метода String.Join вместо вызова функции, которую я написал.

Я имею в виду, я бы просто хотел не писать эту функцию и затем вызывать ее, а написать лямбда-выражение виспользуйте только один раз!

Пример того, как я хотел бы, чтобы это выглядело так:

static void Main(string[] args)
{            
   string @string = "- hello dude! - oh hell yeah hey what's up guy";

   Console.WriteLine(String.Join(".", () => {List<int> ind = new List<int>()..... AND SO ON...} ));
   Console.Read();
}

Ну, на самом деле, я только что понял (при написании этого вопроса), что для такого родаВ ситуации это не нужно, потому что мой метод GetSubStringsIndexes слишком велик.Но представьте, если бы оно было коротким.

Просто скажите мне, возможно ли сделать что-то подобное, и если это возможно, пожалуйста, скажите мне, как!

Редактировать:

Я сделал это, и вот как это выглядит:

        Console.WriteLine(String.Join(".", ((Func<int[]>)
            ( () => 
            {
                List<int> indx = new List<int>();
                int res = @string.IndexOf("he", 0);
                while (res >= 0)
                {
                    indx.Add(res);
                    res = @string.IndexOf("he", res + "he".Length);
                }
                return indx.ToArray();
            }
            ))()));

Ответы [ 4 ]

0 голосов
/ 24 сентября 2018

Окончательный результат:

Console.WriteLine(String.Join(".", ((Func<int[]>)
    ( () => 
    {
        List<int> indx = new List<int>();
        int res = @string.IndexOf("he", 0);
        while (res >= 0)
        {
            indx.Add(res);
            res = @string.IndexOf("he", res + "he".Length);
        }
        return indx.ToArray();
    }
))()));
0 голосов
/ 19 сентября 2018

Один из способов сделать это - использовать оператор Select, в котором вы фиксируете как проверяемый символ, так и его индекс в строке (используя синтаксис: Select((item, index) => ...), а затем, если в этом случае существует подстрока.index, верните индекс, в противном случае верните -1 (из оператора Select), а затем добавьте предложение Where для удаления любых результатов -1.

Код немногодолго, потому что мы также должны быть уверены, что мы не слишком близко к концу строки, прежде чем проверять подстроку (что приводит к другому троичному условию, которое возвращает -1).

Я уверен, что это можно улучшить, но это начало:

string @string = "- hello dude! - oh hell yeah hey what's up guy";           

var subString = "he";

Console.WriteLine(string.Join(".", @string.Select((chr, index) =>
    index + subString.Length < @string.Length
        ? @string.Substring(index, subString.Length) == subString
            ? index
            : -1
        : -1)
    .Where(result => result > -1)));

В случае, если это слишком сложно для чтения (из-за множественных ?: троичных выражений), вот онос комментариями перед каждой строкой:

// For each character in the string, grab the character and it's index
Console.WriteLine(string.Join(".", @string.Select((chr, index) =>
    // If we're not too close to the end of the string
    index + subString.Length < @string.Length
        // And the substring exists at this index          
        ? @string.Substring(index, subString.Length) == subString
            // Return this index
            ? index
            // Substring not found here; return -1
            : -1
        // We're too close to end; return -1
        : -1) 
    // Return only the indexes where the substring was found
    .Where(result => result > -1)));
0 голосов
/ 19 сентября 2018

Ваше "улучшение" в вопросе работает.Вот более краткий способ сделать это с помощью вспомогательной функции, которую нужно определить только один раз:

static void Execute<TReturn>(Func<TReturn> func) => func();

Тогда:

Console.WriteLine(Execute(() => { /* any code here */ }));

Это автоматически выводит тип делегата и вызываетделегировать.Это устраняет много беспорядка.

В общем, я бы посоветовал против этого стиля.Вместо этого используйте несколько строк кода.

0 голосов
/ 19 сентября 2018

То, что вы хотите, невозможно, так как String.join() не принимает Func<int[]> или Expression<Func<int[]>>.

. Вы можете использовать локальную функцию и вызывать ее, если вы этого не сделаетехочу написать метод расширения.

static void Main(string[] args)
{            
   string @string = "- hello dude! - oh hell yeah hey what's up guy";

   Console.WriteLine(String.Join(".", GetIndexes('he'));
   Console.Read();

   int[] GetIndexes(string substring) {
       var indexes = new List<int>();
       // compute indexes as desired. @string is available here.
       return indexes.ToArray();
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...