Как рефакторинг этого метода C # Window - PullRequest
0 голосов
/ 01 октября 2009

У меня есть TextBox для поиска всех вхождений введенного текста в RichTextBox Control. Результат будет заполнен в списке для выбора пути обхода после того, как поиск закончится.

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

Короче говоря, мне нужно реализовать функцию FindAll ..

public void FindSearchResults(string searchWord)
{
    CheckState matchCase = default(CheckState);
    CheckState matchWholeWords = default(CheckState);
    RichTextBox tvc = this._rt;
    List<string> retVal = new List<string>();
    RichTextBoxFinds FindOptions = default(RichTextBoxFinds);

    currentSearchWord = searchWord;
    FindOptions = RichTextBoxFinds.None;
    // Location to begin the search. 
    FindOptions = RichTextBoxFinds.None;

    int searchResult = -2;
    int start = 0;
    string expandedValue = "";
    if ((matchWholeWords == CheckState.Checked) & (matchCase == CheckState.Checked))
    {
        FindOptions = RichTextBoxFinds.MatchCase | RichTextBoxFinds.WholeWord;
    }
    else if ((matchWholeWords == CheckState.Checked))
    {
        FindOptions = RichTextBoxFinds.WholeWord;
    }
    else if ((matchCase == CheckState.Checked))
    {
        FindOptions = RichTextBoxFinds.MatchCase;
    }
    else
    {
        FindOptions = RichTextBoxFinds.None;
    }
    while (searchResult != -1 & start < tvc.Text.Length)
    {
        searchResult = tvc.Find(searchWord, start, FindOptions);
        if ((searchResult != -1))
        {
            expandedValue = Expand(searchWord, searchResult);
            while (searchResultList.ContainsKey(expandedValue))
            {
                // just to keep uniqueness 
                expandedValue = expandedValue + " ";
            }

            retVal.Add(expandedValue);
            searchResultList[expandedValue] = searchResult;
            start = searchResult + searchWord.Length;
        }
    }

}

private string Expand(string searchWord, int searchResult)
{
    string retVal = null;
    int startPos = 0;
    int endPos = 0;
    int spaceCount = 0;
    RichTextBox tvc = this._rt;

    startPos = searchResult;
    spaceCount = 0;
    while (spaceCount < 2 & startPos > 0)
    {
        startPos = startPos - 1;
        char[] ch=tvc.Text.Substring(startPos,1).ToCharArray();
        if (ch[0] == (Char)32)
        {
            spaceCount = spaceCount + 1;
        }
    }

    spaceCount = 0;
    endPos = searchResult + 1;

    while (spaceCount < 4 & endPos < tvc.Text.Length)
    {
        int asciiVal = 0;
        asciiVal = Strings.Asc(tvc.Text.Substring(endPos,1));
        if (asciiVal == 10 | asciiVal == 13 | asciiVal == 32)
        {
            spaceCount = spaceCount + 1;
        }
        endPos = endPos + 1;
    }

    retVal = tvc.Text.Substring(startPos, endPos - startPos);
    retVal = retVal.Replace(Environment.NewLine, string.Empty);
    return retVal;
} 

Ответы [ 2 ]

0 голосов
/ 02 октября 2009

Этот код не является самым чистым и может определенно использовать рефакторинг, но я думаю, что вы, вероятно, должны смотреть на выполнение метода Find в блоках при поиске текста. Кроме того, когда вы ищете стоп-символы, такие как '', вы должны искать по частям. Кажется, мои запросы выполняются довольно быстро по сравнению с методом Find.

private void FindButton_Click(object sender, EventArgs e)
    {
        findOptions = default(RichTextBoxFinds);
        resultsListBox.Items.Clear();

        if (MatchCaseCheckBox.Checked)
        {
            findOptions = findOptions | RichTextBoxFinds.MatchCase;
        }

        if (MatchEntireWordCheckBox.Checked)
        {
            findOptions = findOptions | RichTextBoxFinds.WholeWord;
        }

        int[] foundLocations = FindSearchResults(TextToSearchTextBox.Text.Trim());
        string[] words = null;
        if (foundLocations.Length > 0)
        {
            words = GetWords(foundLocations);

        }
        foreach (string word in words)
        {
            resultsListBox.Items.Add(word);
        }
    }

    private string[] GetWords(int[] foundLocations)
    {
        string textChunk = string.Empty;
        int chunkSize = 64;
        int textLength = MyRichTextBox.TextLength;
        int startIndex = 0;
        int endIndex = 0;
        List<string> words = new List<string>();
        int lastSpaceIndex = -1;
        int firstSpaceIndex = -1;
        foreach (int location in foundLocations)
        {
            textChunk = string.Empty;
            startIndex = location;
            endIndex = location;
            firstSpaceIndex = -1;
            lastSpaceIndex = -1;

            //get the start index.
            while (startIndex >= 0)
            {
                if (startIndex - chunkSize >= 0)
                {
                    startIndex -= chunkSize;
                }
                else
                {
                    startIndex -= Math.Abs(startIndex);
                }

                textChunk += MyRichTextBox.Text.Substring(startIndex, location - startIndex);
                firstSpaceIndex = textChunk.LastIndexOf(' ');
                if (firstSpaceIndex > -1)
                {
                    firstSpaceIndex = location - (textChunk.Length - firstSpaceIndex);
                    break;
                }
            }
            textChunk = string.Empty;
            startIndex = location;
            if (firstSpaceIndex == -1)
            {
                firstSpaceIndex = 0;
            }

            while (textChunk.Length <= textLength)
            {
                if (chunkSize + location < textLength)
                {
                    endIndex = chunkSize;
                }
                else
                {
                    endIndex = (textLength - startIndex);
                }

                textChunk += MyRichTextBox.Text.Substring(firstSpaceIndex + 1,
                    endIndex);
                lastSpaceIndex = textChunk.IndexOf(' ');
                if (lastSpaceIndex > -1)
                {
                    words.Add(textChunk.Substring(0, lastSpaceIndex));
                    break;
                }
            }
        }
        return words.ToArray();
    }

    private int[] FindSearchResults(string textToSearchFor)
    {

        int textLength = MyRichTextBox.TextLength;
        int chunkSize = 128;
        int startIndex = 0;
        int endIndex = 0;
        int foundIndex = -1;
        List<int> foundLocations = new List<int>();

        while (startIndex < textLength)
        {
            if ((chunkSize + startIndex) < textLength)
            {
                endIndex += chunkSize;
            }
            else
            {
                endIndex += textLength - endIndex;
            }

            foundIndex = MyRichTextBox.Find(textToSearchFor, startIndex, endIndex, findOptions);
            if (foundIndex > -1)
            {
                foundLocations.Add(foundIndex);
            }
            startIndex += chunkSize;
        }

        return foundLocations.ToArray();
    }
0 голосов
/ 01 октября 2009

ИМХО ваш код не очень понятен в настоящее время. Для начала я бы:

  • Выполнить четкое разделение между битами, определяющими параметры поиска
  • Выполнить фактический поиск (этот метод не должен ссылаться ни на какие компоненты пользовательского интерфейса)
  • Показать результаты

Неясно (по крайней мере для меня), что делают ваши методы. Что делает метод Expand? Почему используется окно редактирования?

...