5

リストの最初と最後にある空の行をすべて削除する必要List<string>があります。

注: 空行はコンテンツのない行と見なされますが、空白とタブが含まれる可能性があります。これは、行が空かどうかを確認する方法です。

    private bool HasContent(string line)
    {
        if (string.IsNullOrEmpty(line))
            return false;

        foreach (char c in line)
        {
            if (c != ' ' && c != '\t')
                return true;
        }

        return false;
    }

それを行うために、どのような効率的で読みやすいコードを提案しますか?

確認例

[" ", " ", " ", " ", "A", "B", " ", "C", " ", "D", " ", " ", " "]

このようなリストは、次の結果の最初最後にあるすべての空行を削除して、トリミングする必要があります。

["A", "B", " ", "C", " ", "D"]
4

10 に答える 10

8
var results = textLines1.SkipWhile(e => !HasContent(e))
                        .Reverse()
                        .SkipWhile(e => !HasContent(e))
                        .Reverse()
                        .ToList();

使い方?リストの先頭にあるすべての空行をスキップし、逆にして同じことを行います (実際には、リストの後ろからすべての空行をスキップします)。別のリバースの後、正しい順序で適切な結果が得られます。

リストが非常に大きい場合はwhile、パフォーマンスを考慮して、標準のループとリストのインデックス作成を使用することを検討できますが、通常のデータ転送では、復帰はそれほど重要ではありません。

于 2013-03-12T09:56:36.980 に答える
4

まず、これをチェックする組み込みメソッドがあります。String.IsNullOrWhiteSpace();

ColinE が提供する回答は、最初または最後だけでなく、空のすべての行を削除するため、要件を満たしていません。

独自のソリューションを構築する必要があると思います:

int start = 0, end = sourceList.Count - 1;

while (start < end && String.IsNullOrWhiteSpace(sourceList[start])) start++;
while (end >= start && String.IsNullOrWhiteSpace(sourceList[end])) end--;

return sourceList.Skip(start).Take(end - start + 1);
于 2013-03-12T10:01:09.287 に答える
2

Linq を使用すると、次の操作を実行できます。

IEnumerable<string> list  = sourceList.SkipWhile(source => !HasContent(source))
                                      .TakeWhile(source => HasContent(source));

これは、コンテンツのある文字列が見つかるまで文字列を「スキップ」し、コンテンツのない文字列が見つかるまですべての文字列を「取得」します。

@MarcinJuraszekが指摘しているように、これはリストの最後にあるものを削除するのではなく、コンテンツを持たない最初の行の後に停止します。

これを行うには、次を使用できます。

IEnumerable<string> list  = sourceList.SkipWhile(source => !HasContent(source))
                                      .Reverse()
                                      .SkipWhile(source => !HasContent(source))
                                      .Reverse();

少し複雑ですが、うまくいくはずです。

于 2013-03-12T09:54:33.383 に答える
2

今行ったこの拡張メソッドを確認してください。

public static class ListExtensions
{
    public static List<string> TrimList(this List<string> list)
    {
        int listCount = list.Count;
        List<string> listCopy = list.ToList();
        List<string> result = list.ToList();

        // This will encapsulate removing an item and the condition to remove it.
        // If it removes the whole item at some index, it return TRUE.
        Func<int, bool> RemoveItemAt = index =>
        {
            bool removed = false;

            if (string.IsNullOrEmpty(listCopy[index]) || string.IsNullOrWhiteSpace(listCopy[index]))
            {
                result.Remove(result.First(item => item == listCopy[index]));
                removed = true;
            }

            return removed;
        };

        // This will encapsulate the iteration over the list and the search of 
        // empty strings in the given list
        Action RemoveWhiteSpaceItems = () =>
        {
            int listIndex = 0;

            while (listIndex < listCount && RemoveItemAt(listIndex))
            {
                listIndex++;
            }
        };

        // Removing the empty lines at the beginning of the list
        RemoveWhiteSpaceItems();

        // Now reversing the list in order to remove the 
        // empty lines at the end of the given list
        listCopy.Reverse();
        result.Reverse();

        // Removing the empty lines at the end of the list
        RemoveWhiteSpaceItems();

        // Reversing again in order to recover the right list order.
        result.Reverse();

        return result;
    }
}

...そしてその使用法:

List<string> list = new List<string> { "\t", " ", "    ", "a", "b", "\t", "         ", " " };

// The TrimList() extension method will return a new list without
// the empty items at the beginning and the end of the sample list!
List<string> trimmedList = list.TrimList();
于 2013-03-12T10:13:04.880 に答える
2

このアプローチは、目的のプロパティを持つ新しいオブジェクトを作成する代わりに、元のオブジェクトを変更します。 List<string>

static void TrimEmptyLines(List<string> listToModify)
{
  if (listToModify == null)
    throw new ArgumentNullException();

  int last = listToModify.FindLastIndex(HasContent);
  if (last == -1)
  {
    // no lines have content
    listToModify.Clear();
    return;
  }
  int count = listToModify.Count - last - 1;
  if (count > 0)
    listToModify.RemoveRange(last + 1, count);

  int first = listToModify.FindIndex(HasContent);
  if (first > 0)
    listToModify.RemoveRange(0, first);
}

このコードでHasContentは、元の質問のメソッドです。代わりに、デリゲートにラムダのような無名関数を使用できます。

于 2013-03-12T12:16:47.770 に答える
1

以下のコードは、必要なことを行います。

List<string> lines = new List<string> {"   \n\t", " ", "aaa", "  \t\n", "bb", "\n", " "};
IEnumerable<string> filtered = lines.SkipWhile(String.IsNullOrWhiteSpace).Reverse().SkipWhile(String.IsNullOrWhiteSpace).Reverse();

リストを 2 回逆にするため、パフォーマンスが重要な場合は理想的なソリューションではない可能性があります。

于 2013-03-12T09:58:28.733 に答える
-1
List<string> name = new List<string>();
name.Add("              ");
name.Add("rajesh");
name.Add("raj");
name.Add("rakesh");
name.Add("              ");
for (int i = 0; i < name.Count(); i++)
{
  if (string.IsNullOrWhiteSpace(Convert.ToString(name[i])))
  {
    name.RemoveAt(i);
  }
}
于 2013-03-12T10:09:28.007 に答える
-1

isullorwhitespaceを使用 してこれを確認できます。以下の例を参照してください。

        List<string> lines = new List<string>();
        lines.Add("         ");
        lines.Add("one");
        lines.Add("two");
        lines.Add("");
        lines.Add("");
        lines.Add("five");
        lines.Add("");
        lines.Add("       ");
        lines.RemoveAll(string.IsNullOrWhiteSpace);
于 2013-03-12T10:06:25.120 に答える
-2

あなたのコードのフォームに関しては、あなたの行には空白もタブも含まれていないと思うのでforeach

if(line.Contains(' ') || line.Contains('\t'))
   return false;
return true;
于 2013-03-12T09:54:38.857 に答える
-2
List<string> name = new List<string>();
name.Add("              ");
name.Add("rajesh");
name.Add("raj");
name.Add("rakesh");
name.Add("              ");

name.RemoveAt(0);
name.RemoveAt(name.Count() - 1);
于 2013-03-12T10:06:02.347 に答える