배열 값을 한 줄로 분리 변수에 할당
-
07-07-2019 - |
문제
C#의 한 줄로 변수를 분리하기 위해 배열에서 각 값을 할당 할 수 있습니까? 다음은 내가 원하는 것의 루비 코드의 예입니다.
irb(main):001:0> str1, str2 = ["hey", "now"]
=> ["hey", "now"]
irb(main):002:0> str1
=> "hey"
irb(main):003:0> str2
=> "now"
내가 원하는 것이 C#에서 가능한지 확실하지 않습니다.
편집하다: 제안을 제안하는 사람들은 내가 "Hey"와 "Now"를 변수에 할당하는 것이 아닙니다. 그것이 내가 원하는 것이 아닙니다. 다음을 상상해보십시오.
irb(main):004:0> val1, val2 = get_two_values()
=> ["hey", "now"]
irb(main):005:0> val1
=> "hey"
irb(main):006:0> val2
=> "now"
이제 방법이 사실입니다 get_two_values
반환 된 문자열 "Hey"와 "Now"는 임의적입니다. 실제로 두 값을 반환 할 수 있으며 문자열 일 필요조차 없습니다.
해결책
C#에서는 불가능합니다.
내가 생각할 수있는 가장 가까운 것은 인덱스와 같은 선에서 초기화를 사용하는 것입니다.
strArr = new string[]{"foo","bar"};
string str1 = strArr[0], str2 = strArr[1];
다른 팁
업데이트: C#7에서는 튜플을 사용하여 한 번에 여러 변수를 쉽게 할당 할 수 있습니다. 배열 요소를 변수에 할당하려면 적절한 것을 작성해야합니다. Deconstruct()
확장 방법 :
튜플을 소비하는 또 다른 방법은 튜플을 해체하는 것입니다. 해체 선언은 튜플 (또는 다른 값)을 해당 부품으로 분할하고 해당 부품을 새로운 변수에 개별적으로 할당하는 구문입니다.
(string first, string middle, string last) = LookupName(id1); // deconstructing declaration WriteLine($"found {first} {last}.");
해체 선언에서는 개별 변수에 VAR을 사용할 수 있습니다.
(var first, var middle, var last) = LookupName(id1); // var inside
또는 괄호 안에 단일 VAR을 약어로 넣습니다.
var (first, middle, last) = LookupName(id1); // var outside
해체 할당을 통해 기존 변수로 해체 할 수도 있습니다.
(first, middle, last) = LookupName(id2); // deconstructing assignment
해체는 튜플을위한 것이 아닙니다. 양식의 (인스턴스 또는 확장) 해체 방법이있는 한 모든 유형이 해체 될 수 있습니다.
public void Deconstruct(out T1 x1, ..., out Tn xn) { ... }
OUT 매개 변수는 해체로 인한 값을 구성합니다.
(튜플을 반환하는 대신 매개 변수를 사용하는 이유는 무엇입니까? 즉, 다른 값의 값에 대해 여러 오버로드를 가질 수 있습니다).
class Point { public int X { get; } public int Y { get; } public Point(int x, int y) { X = x; Y = y; } public void Deconstruct(out int x, out int y) { x = X; y = Y; } } (var myX, var myY) = GetPoint(); // calls Deconstruct(out myX, out myY);
이런 식으로 생성자와 디스크 러너를 "대칭"하는 것이 일반적인 패턴이 될 것입니다. https://blogs.msdn.microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/
오래된 답변 :
실제로 이와 같은 확장 방법을 사용하여 C#에서 유사한 기능을 달성 할 수 있습니다 (참고 : 인수가 유효한지 확인하지 않음).
public static void Match<T>(this IList<T> collection, Action<T,T> block)
{
block(collection[0], collection[1]);
}
public static void Match<T>(this IList<T> collection, Action<T,T,T> block)
{
block(collection[0], collection[1], collection[2]);
}
//...
다음과 같이 사용할 수 있습니다.
new[] { "hey", "now" }.Match((str1, str2) =>
{
Console.WriteLine(str1);
Console.WriteLine(str2);
});
함수의 반환 값이 필요한 경우 다음 과부하가 작동합니다.
public static R Match<T,R>(this IList<T> collection, Func<T, T, R> block)
{
return block(collection[0], collection[1]);
}
private string NewMethod1()
{
return new[] { "hey", "now" }.Match((str1, str2) =>
{
return str1 + str2;
});
}
이런 식으로:
Jaredpar와 다른 사람들이 제안한 솔루션에서와 같이 배열 이름을 반복하지 않아도됩니다. "변수"목록은 읽기 쉽습니다.
Daniel Earwicker의 솔루션과 같은 변수 유형을 명시 적으로 선언하지 않아도됩니다.
단점은 추가 코드 블록으로 끝나는 것이지만 그만한 가치가 있다고 생각합니다. 교정기 등을 입력하지 않기 위해 코드 스 니펫을 사용할 수 있습니다. 수동으로.
나는 그것이 7 년 된 질문이라는 것을 알고 있지만 오래 전에 그런 솔루션이 필요하지 않았다 - 어레이 대신에 클래스/structs를 사용하여 실용적이지 않았기 때문에, 배열 요소에 쉽게 이름을 부여합니다. 다른 방법으로 다른 요소 이름이 필요할 수 있습니다.) 불행히도 다음과 같은 코드로 끝났습니다.
var A = points[0];
var A2 = points[1];
var B = points[2];
var C2 = points[3];
var C = points[4];
이제 나는 쓸 수 있습니다 (사실, 나는 지금 그 방법 중 하나를 리팩토링했습니다!) : :
points.Match((A, A2, B, C2, C) => {...});
내 솔루션은 F#의 패턴 일치와 유사 하며이 답변에서 영감을 받았습니다. https://stackoverflow.com/a/2321922/6659843
이를위한 실제 사용 사례는 함수에서 여러 값을 반환하는 편리한 방법을 제공하는 것입니다. 따라서 배열에서 고정 된 수의 값을 반환하는 루비 함수이며 발신자는 두 개의 별도 변수로 원합니다. 기능이 가장 의미가있는 곳입니다.
first_name, last_name = get_info() // always returns an array of length 2
이것을 c#로 표현하려면 두 매개 변수를 다음과 같이 표시합니다. out
메소드 정의 및 반환에서 void
:
public static void GetInfo(out string firstName, out string lastName)
{
// assign to firstName and lastName, instead of trying to return them.
}
그리고 그것을 부르기 위해 :
string firstName, lastName;
SomeClass.GetInfo(out firstName, out lastName);
그렇게 좋지 않습니다. C#의 미래 버전이 다음을 허용하기를 바랍니다.
var firstName, lastName = SomeClass.GetInfo();
이것을 가능하게하기 위해 GetInfo
메소드는 a를 반환합니다 Tuple<string, string>
. 이것은 현재의 법적 사용으로 언어에 대한 무너지지 않는 변화 일 것입니다. var
매우 제한적이므로 위의 "다중 선언"구문에는 아직 유효한 용도가 없습니다.
한 줄로 할 수 있지만 한 줄로 할 수는 없습니다.
예를 들어:
int str1 = "hey"; int str2 = "now";
파이썬과 루비는 당신이하려는 과제를지지합니다. C#은 그렇지 않습니다.
내가 원하는 것이 C#에서 가능한지 확실하지 않습니다.
그렇지 않습니다.
C# 에서이 작업을 수행 할 수 있습니다.
string str1 = "hey", str2 = "now";
아니면 이렇게 멋진 사람이 될 수 있습니다
int x, y;
int[] arr = new int[] { x = 1, y = 2 };
아니요,하지만 다양한 문자열을 초기화 할 수 있습니다.
string[] strings = new string[] {"hey", "now"};
그것은 아마도 당신에게 너무 유용하지는 않지만. 솔직히 두 줄에 두는 것은 어렵지 않습니다.
string str1 = "hey";
string str2 = "now";
당신은 이름이 지정된 튜플을 사용할 수 있습니다 C# 7 지금.
{
(string part1, string part2) = Deconstruct(new string[]{"hey","now"});
}
public (string, string) Deconstruct(string[] parts)
{
return (parts[0], parts[1]);
}