testList
많은 문자열을 포함 하는 목록 이 있습니다. testList
목록에없는 경우에만 새 문자열을 추가하고 싶습니다 . 따라서 대소 문자를 구분하지 않고 목록을 검색하고 효율적으로 만들어야합니다. Contains
케이스를 고려하지 않기 때문에 사용할 수 없습니다 . 또한 ToUpper/ToLower
성능상의 이유로 사용하고 싶지 않습니다 . 나는이 방법을 발견했다.
if(testList.FindAll(x => x.IndexOf(keyword,
StringComparison.OrdinalIgnoreCase) >= 0).Count > 0)
Console.WriteLine("Found in list");
이것은 작동하지만 부분 단어와도 일치합니다. 목록에 “염소”가 포함되어 있으면 “귀리”가 이미 목록에 있다고 주장하기 때문에 “귀리”를 추가 할 수 없습니다. 단어가 정확히 일치해야하는 대소 문자를 구분하지 않는 방식으로 목록을 효율적으로 검색하는 방법이 있습니까? 감사
답변
String.IndexOf 대신 String.Equals 를 사용 하여 부분 일치가 없는지 확인하십시오. 또한 모든 요소를 통과하는 FindAll을 사용하지 말고 FindIndex를 사용 하십시오 (첫 번째 요소는 중지합니다).
if(testList.FindIndex(x => x.Equals(keyword,
StringComparison.OrdinalIgnoreCase) ) != -1)
Console.WriteLine("Found in list");
또는 일부 LINQ 방법을 사용하십시오 (첫 번째 방법에서도 중지됨)
if( testList.Any( s => s.Equals(keyword, StringComparison.OrdinalIgnoreCase) ) )
Console.WriteLine("found in list");
답변
나는 이것이 오래된 게시물이라는 것을 알고 있지만 다른 사람이 찾고 있는 경우를 대비하여 대소 문자를 구분하지 않는 문자열 동등 비교기를 제공하여 사용할 수 있습니다 Contains
.
using System.Linq;
// ...
if (testList.Contains(keyword, StringComparer.OrdinalIgnoreCase))
{
Console.WriteLine("Keyword Exists");
}
이것은 msdn 에 따라 .net 2.0부터 사용 가능 합니다.
답변
위의 Adam Sills 답변을 기반으로-Contains … 🙂
///----------------------------------------------------------------------
/// <summary>
/// Determines whether the specified list contains the matching string value
/// </summary>
/// <param name="list">The list.</param>
/// <param name="value">The value to match.</param>
/// <param name="ignoreCase">if set to <c>true</c> the case is ignored.</param>
/// <returns>
/// <c>true</c> if the specified list contais the matching string; otherwise, <c>false</c>.
/// </returns>
///----------------------------------------------------------------------
public static bool Contains(this List<string> list, string value, bool ignoreCase = false)
{
return ignoreCase ?
list.Any(s => s.Equals(value, StringComparison.OrdinalIgnoreCase)) :
list.Contains(value);
}
답변
StringComparer를 사용할 수 있습니다 :
var list = new List<string>();
list.Add("cat");
list.Add("dog");
list.Add("moth");
if (list.Contains("MOTH", StringComparer.OrdinalIgnoreCase))
{
Console.WriteLine("found");
}
답변
랜스 라슨 (Lance Larsen) 답변을 기반으로-권장 문자열이있는 확장 방법이 있습니다. 문자열 대신 비교하십시오.
StringComparison 매개 변수를 사용하는 String.Compare의 오버로드를 사용하는 것이 좋습니다. 이러한 오버로드를 통해 의도 한 정확한 비교 동작을 정의 할 수있을뿐만 아니라이를 사용하면 다른 개발자가 코드를보다 쉽게 읽을 수 있습니다. [ 조쉬 프리 @ BCL 팀 블로그 ]
public static bool Contains(this List<string> source, string toCheck, StringComparison comp)
{
return
source != null &&
!string.IsNullOrEmpty(toCheck) &&
source.Any(x => string.Compare(x, toCheck, comp) == 0);
}
답변
IndexOf의 결과가 0보다 크거나 같은지 여부를 확인 중 입니다. 즉, 문자열의 어느 곳에서나 일치가 시작되는지 여부를 의미합니다 . 0 과 같은지 확인하십시오 .
if (testList.FindAll(x => x.IndexOf(keyword,
StringComparison.OrdinalIgnoreCase) >= 0).Count > 0)
Console.WriteLine("Found in list");
이제 “염소”와 “귀리”는 일치하지 않지만 “염소”와 “고아”는 일치합니다. 이를 피하기 위해 두 줄의 길이를 비교할 수 있습니다.
이 모든 합병증을 피하기 위해 목록 대신 사전을 사용할 수 있습니다. 키는 소문자 문자열이고 값은 실제 문자열입니다. 이렇게하면 ToLower
각 비교 에 사용할 필요 가 없기 때문에 성능이 저하되지 않지만 여전히을 사용할 수 있습니다 Contains
.
답변
아래는 전체 목록에서 키워드를 검색하고 해당 항목을 제거하는 예입니다.
public class Book
{
public int BookId { get; set; }
public DateTime CreatedDate { get; set; }
public string Text { get; set; }
public string Autor { get; set; }
public string Source { get; set; }
}
Text 속성에 키워드가 포함 된 책을 제거하려면 키워드 목록을 만들어 책 목록에서 제거 할 수 있습니다.
List<Book> listToSearch = new List<Book>()
{
new Book(){
BookId = 1,
CreatedDate = new DateTime(2014, 5, 27),
Text = " test voprivreda...",
Autor = "abc",
Source = "SSSS"
},
new Book(){
BookId = 2,
CreatedDate = new DateTime(2014, 5, 27),
Text = "here you go...",
Autor = "bcd",
Source = "SSSS"
}
};
var blackList = new List<string>()
{
"test", "b"
};
foreach (var itemtoremove in blackList)
{
listToSearch.RemoveAll(p => p.Source.ToLower().Contains(itemtoremove.ToLower()) || p.Source.ToLower().Contains(itemtoremove.ToLower()));
}
return listToSearch.ToList();
