값이 배열에 있는지 확인 (C #)


109

값이 C #의 배열에 있는지 어떻게 확인합니까?

마찬가지로 프린터 이름 목록으로 배열을 만들고 싶습니다.

이들은 각 문자열을 차례로 살펴보고 문자열이 배열의 값과 같으면 해당 작업을 수행하는 메서드에 제공됩니다.

예를 들면 :

string[] printer = {"jupiter", "neptune", "pangea", "mercury", "sonic"};
foreach (p in printer)
{
   PrinterSetup(p);     
}

이것은 PrinterSetup 메서드에 공급되는 프린터의 이름입니다.

PrinterSetup은 다음과 같습니다 (일부 의사 코드).

public void PrinterSetup(printer)
{
   if (printer == "jupiter") 
   {
      Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC");
   }
}

if (printer == "jupiter")C #이 인식 할 수있는 방식으로 서식 을 지정하려면 어떻게해야 합니까?


4
매개 변수 이름에 유형 (문자열)을 지정하면 괜찮습니다.
Jon Skeet

2
나는 질문으로 다소 혼란 스럽습니다. 값이 배열에 있는지 확인하는 방법 또는 C #에서 문자열 비교를 수행하는 방법을 묻고 있습니까? 후자의 경우 printer.Equals("jupiter"). 전자 인 경우 linqprinter.Contains("jupiter")
newfurniturey

@newfurniturey 아주 그렇습니다 ... 질문이 혼란스럽고 예제 코드가 제목과 일치하지 않으므로 대답도 마찬가지로 혼란 스럽습니다. 이런 쓰레기가 찬성되는 이유는 나를 넘어선 다. 그리고 할 필요가 없습니다 printer.Equals("jupiter")... OP의 코드 if (printer == "jupiter")는 잘 작동합니다 ... printerSkeet이 언급했듯이 문자열로 선언되는 한 ...
Jim Balter

답변:


231

필요한 네임 스페이스 추가

using System.Linq;

그런 다음 linq Contains()방법을 사용할 수 있습니다.

string[] printer = {"jupiter", "neptune", "pangea", "mercury", "sonic"};
if(printer.Contains("jupiter"))
{
    Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC"");
}

2
@ 0A0D. 이 대답은 동일한 것을 달성하는 가장 간단하고 가장 짧고 잘 알려진 방법이라고 생각 How do I check if a value is in an array in C#?합니다. 루프가 없으며 추가 방법이 없습니다. 네임 스페이스는 큰 것이 아닌 여분입니다.
Sami 2011

6
@Sami : Linq는 내부적으로 루프를 사용합니다.

2
@ 0A0D Sam은 아마도 컴파일 된 명령어가 아니라 작성된 코드를 참조하고있을 것입니다. Linq는 내부적으로 루프와 메서드를 사용하지만 코더의 관점에서 볼 때 숨겨져 있고 걱정할 필요가 없습니다.
nov.

1
오른쪽 @ 0A0D. 저는 코더 / 개발자가 올바른 루프를 할 필요가 없다는 것을 의미했습니다. 어레이의 오프 코스 체크에는 루프가 필요합니다 :)
Sami

3
이것은 확실히 쉽고 추천 할 만합니다. Linq에 대한 액세스 권한이 없거나 Linq를 사용하지 않으려 는 경우 배열의 명시 적 인터페이스 구현 에 의존 할 수 있습니다 . .NET 1.1부터는 ((IList)printer).Contains("Jupiter")제네릭이 아니고 (박스 값 유형 등) 다차원 배열에서도 작동합니다. 그리고 .NET 2.0 이후로 우리 ((IList<string>)printer).Contains("Jupiter")는 더 유형이 안전한 더 마법 을 가지고 있습니다. Linq 접근 방식은 .NET 3.5의 새로운 기능입니다.
Jeppe Stig Nielsen

29
   string[] array = { "cat", "dot", "perls" };

// Use Array.Exists in different ways.
bool a = Array.Exists(array, element => element == "perls");
bool b = Array.Exists(array, element => element == "python");
bool c = Array.Exists(array, element => element.StartsWith("d"));
bool d = Array.Exists(array, element => element.StartsWith("x"));

// Display bools.
Console.WriteLine(a);
Console.WriteLine(b);
Console.WriteLine(c);
Console.WriteLine(d);
----------------------------output-----------------------------------

1) 참 2) 거짓 3) 참 4) 거짓


6
이것은 받아 들여진 대답이어야합니다. 어레이를 사용하는 경우 그 성능이 중요합니다. 이 경우 Linq는 종종 잘못된 선택입니다.
Philm

22
if ((new [] {"foo", "bar", "baaz"}).Contains("bar"))
{

}  

이것은 일반적인 예입니다. 질문에 더 잘 맞는 것을 제공 할 수 있습니까?
kaz

9
일반적인 예 일지 모르지만 정확히 내가 찾던 것입니다.
Grant Birchmeier

7

이 같은?

string[] printer = {"jupiter", "neptune", "pangea", "mercury", "sonic"};
PrinterSetup(printer);

// redefine PrinterSetup this way:
public void PrinterSetup(string[] printer)
{
    foreach (p in printer.Where(c => c == "jupiter"))
    {
        Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC"");
    }
}

7
    public static bool Contains(Array a, object val)
    {
        return Array.IndexOf(a, val) != -1;
    }

2
나는 이것을 좋아한다. 그러나 a다차원 배열 (예 : new string[10, 20, 15]예외) 인 경우 에는 실패합니다 . 또한 0에서 인덱싱되지 않은 1 차원 배열 (예 : Array.CreateInstance(typeof(string), new[] { 5, }, new[] { -2, })C #에서 드물게 인정)과 함께 잘못된 반환 값으로 실패합니다. 이러한 단점은 제네릭으로 쉽게 수정할 수 있습니다.public static bool Contains<TElement>(TElement[] a, TElement val) { return Array.IndexOf(a, val) != -1; }
Jeppe Stig Nielsen

나는 이것을 좋아하지만 Linq가 없기 때문에 IndexOf가 남은 유일한 것임을 확인합니다 .
Bitterblue

6

참고 : 문제는 문자열 배열에 관한 것입니다. 언급 된 루틴은 단일 문자열의 .Contains 메소드와 혼합되어서는 안됩니다.

다른 C # 버전과 두 가지 이유로 인해 확장 답변을 추가하고 싶습니다.

  • 허용되는 답변에는 비용 없이는 제공되지 않고 C # 2.0 이하에서는 사용할 수 없지만 완벽하게 관용적 인 C # 인 Linq가 필요합니다. 어레이가 관련되면 성능이 중요 할 수 있으므로 Array 메서드를 유지하려는 상황이 있습니다.

  • 이것을 함수에 넣도록 요청받은 질문에 대한 대답은 없습니다 (일부 답변은 문자열과 문자열 배열을 혼합하기 때문에 완전히 중요하지 않습니다).

Array.Exists ()는 C # /. NET 2.0 메서드이며 Linq가 필요하지 않습니다. 배열 검색은 O (n)입니다. 더 빠른 액세스를 위해 HashSet 또는 유사한 컬렉션을 사용하십시오.

.NET 3.5부터는 일반적인 방법도 있습니다 Array<T>.Exists().

public void PrinterSetup(string[] printer)
{
   if (Array.Exists(printer, x => x == "jupiter"))
   {
      Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC");
   }
}

Linq를 포함하지 않고 모든 배열에 대한 문자열과 동일하거나 유사한 ".Contains"를 얻기 위해 구문 설탕을 추가하는 자체 확장 메서드 (C # 3.0 이상)를 작성할 수 있습니다.

// Using the generic extension method below as requested.
public void PrinterSetup(string[] printer)
{
   if (printer.ArrayContains("jupiter"))
   {
      Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC");
   }
}

public static bool ArrayContains<T>(this T[] thisArray, T searchElement)
{
   // If you want this to find "null" values, you could change the code here
   return Array.Exists<T>(thisArray, x => x.Equals(searchElement));
}

이 경우 ArrayContains() Linq의 Contains 메서드가 아닌 메서드가 사용됩니다.

다른 곳에서 언급 된 .Contains 메서드는 List<T>.Contains(C # 2.0 ArrayList.Contains이후 ) 또는 (C # 1.1 이후)를 참조하지만 배열 자체는 직접 참조하지 않습니다.


1
Linq Contains ()와의 혼동을 피하기 위해 이름을 ArrayContains ()로 변경하는 것이 좋습니다
peter.cyc

반대의 주장도 있지만, 저는 이것을했습니다. 특히 Linq 설정을 염두에두고 다른 데이터 유형에 대해 동일한 이름을 사용하는 것이 다형성의 기본 아이디어입니다. 다른 이름을 사용하는 것은 다형성이 아닙니다. 그러나 가독성과 오해를 피하는 것이 승리 할 것이라고 생각합니다. 그렇습니다.
Philm

4

당신은 당신의 방법에서 무언가를 놓치고 있습니다.

public void PrinterSetup(string printer)
{
   if (printer == "jupiter") 
   {
      Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC"");
   }
}

추가하기 만하면 string괜찮을 것입니다.


3

문제가 무엇인지 명확하지 않지만 다음과 같은 것을 원하는 것 같습니다.

    List<string> printer = new List<string>( new [] { "jupiter", "neptune", "pangea", "mercury", "sonic" } );

    if( printer.Exists( p => p.Equals( "jupiter" ) ) )
    {
        ...
    }

2

조회 성능을 위해 HashSet<T>Class 사용을 고려하십시오 .

이 메서드는 O (1) 작업입니다.

HashSet<T>.Contains방법 (T), MSDN .

예를 들면 :

class PrinterInstaller
{
    private static readonly HashSet<string> PrinterNames = new HashSet<string>
        {
            "jupiter", "neptune", "pangea", "mercury", "sonic"
        };

    public void Setup(string printerName)
    {
        if (!PrinterNames.Contains(printerName))
        {
            throw new ArgumentException("Unknown printer name", "printerName");
        }
        // ...
    }
}

1

목록에서 중복을 찾는 방법과 제거하는 방법을 찾기 위해 2 시간 이상 검색 했습니다 . 가장 간단한 대답은 다음과 같습니다.

//Copy the string array with the filtered data of the analytics db into an list
// a list should be easier to use
List<string> list_filtered_data = new List<string>(analytics_db_filtered_data);

// Get distinct elements and convert into a list again.
List<string> distinct = list_filtered_data.Distinct().ToList();

출력은 다음과 같이 표시됩니다. 중복 된 요소는 distinct!라는 새 목록에서 제거됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.