Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Aralıklar ve dizinler, bir dizideki tek öğelere veya aralıklara erişmek için kısa bir söz dizimi sağlar.
Bu öğreticide şunları nasıl yapacağınızı öğreneceksiniz:
Dizinler ve aralıklar için dil desteği
Dizinler ve aralıklar, bir dizideki tek öğelere veya aralıklara erişmek için kısa bir söz dizimi sağlar.
Bu dil desteği iki yeni türe ve iki yeni işleçe dayanır:
- System.Index bir dizideki indeksi temsil eder.
-
Sondan sayma işlecinden
^dizi indisi, dizinin sonuna göre bir indis olduğunu belirtir. - System.Range bir dizinin alt aralığını temsil eder.
- Bir aralığın başlangıç ve bitişini işlenenleri olarak belirten aralık işleci
...
Dizinler için kurallarla başlayalım. bir dizi sequencedüşünün. Dizin 0 ile aynıdır sequence[0]. Dizin ^0 ile aynıdır sequence[sequence.Length]. İfade sequence[^0], tıpkı sequence[sequence.Length] gibi bir özel durum oluşturur. herhangi bir sayı niçin dizin ^n ile aynıdır sequence.Length - n.
private string[] words = [
// index from start index from end
"first", // 0 ^10
"second", // 1 ^9
"third", // 2 ^8
"fourth", // 3 ^7
"fifth", // 4 ^6
"sixth", // 5 ^5
"seventh", // 6 ^4
"eighth", // 7 ^3
"ninth", // 8 ^2
"tenth" // 9 ^1
]; // 10 (or words.Length) ^0
^1 diziniyle son sözcüğü alabilirsiniz. Başlatmanın altına aşağıdaki kodu ekleyin:
Console.WriteLine($"The last word is < {words[^1]} >."); // The last word is < tenth >.
Aralık, aralığın başlangıcını ve sonunu belirtir. Aralığın başlangıcı kapsayıcıdır, ancak aralığın sonu özeldir; bu, başlangıcın aralığa dahil olduğu ancak sonun aralığa dahil olmadığı anlamına gelir. Aralık [0..^0] tüm aralığı temsil eder ve [0..sequence.Length] de aynı şekilde tüm aralığı temsil eder.
Aşağıdaki kod "second", "third" ve "fourth" sözcükleriyle bir alt aralık oluşturur.
words[1] ile words[3] arası içerir. öğesi words[4] aralıkta değil.
string[] secondThirdFourth = words[1..4]; // contains "second", "third" and "fourth"
// < second >< third >< fourth >
foreach (var word in secondThirdFourth)
Console.Write($"< {word} >");
Console.WriteLine();
Aşağıdaki kod, "dokuzuncu" ve "onuncu" aralıklarını döndürür.
words[^2] ve words[^1] içerir. Bitiş dizini words[^0] dahil değildir.
string[] lastTwo = words[^2..^0]; // contains "ninth" and "tenth"
// < ninth >< tenth >
foreach (var word in lastTwo)
Console.Write($"< {word} >");
Console.WriteLine();
Aşağıdaki örneklerde başlangıç, bitiş veya her ikisi için açık uçlu aralıklar oluşturulur:
string[] allWords = words[..]; // contains "first" through "tenth".
string[] firstPhrase = words[..4]; // contains "first" through "fourth"
string[] lastPhrase = words[6..]; // contains "seventh", "eight", "ninth" and "tenth"
// < first >< second >< third >< fourth >< fifth >< sixth >< seventh >< eighth >< ninth >< tenth >
foreach (var word in allWords)
Console.Write($"< {word} >");
Console.WriteLine();
// < first >< second >< third >< fourth >
foreach (var word in firstPhrase)
Console.Write($"< {word} >");
Console.WriteLine();
// < seventh >< eighth >< ninth >< tenth >
foreach (var word in lastPhrase)
Console.Write($"< {word} >");
Console.WriteLine();
Aralıkları veya dizinleri değişken olarak da bildirebilirsiniz. Değişken daha sonra [ ve ] karakterlerinin içinde kullanılabilir.
Index thirdFromEnd = ^3;
Console.WriteLine($"< {words[thirdFromEnd]} > "); // < eighth >
Range phrase = 1..4;
string[] text = words[phrase];
// < second >< third >< fourth >
foreach (var word in text)
Console.Write($"< {word} >");
Console.WriteLine();
Aşağıdaki örnekte bu seçeneklerin birçok nedeni gösterilmiştir. Farklı birleşimleri denemek için , xve y değerlerini değiştirinz. Deneme yaparken, x değeri y değerinden küçük ve y değeri z değerinden küçük olan geçerli birleşimleri kullanın. Aşağıdaki kodu yeni bir yönteme ekleyin. Farklı birleşimleri deneyin:
int[] numbers = [..Enumerable.Range(0, 100)];
int x = 12;
int y = 25;
int z = 36;
Console.WriteLine($"{numbers[^x]} is the same as {numbers[numbers.Length - x]}");
Console.WriteLine($"{numbers[x..y].Length} is the same as {y - x}");
Console.WriteLine("numbers[x..y] and numbers[y..z] are consecutive and disjoint:");
Span<int> x_y = numbers[x..y];
Span<int> y_z = numbers[y..z];
Console.WriteLine($"\tnumbers[x..y] is {x_y[0]} through {x_y[^1]}, numbers[y..z] is {y_z[0]} through {y_z[^1]}");
Console.WriteLine("numbers[x..^x] removes x elements at each end:");
Span<int> x_x = numbers[x..^x];
Console.WriteLine($"\tnumbers[x..^x] starts with {x_x[0]} and ends with {x_x[^1]}");
Console.WriteLine("numbers[..x] means numbers[0..x] and numbers[x..] means numbers[x..^0]");
Span<int> start_x = numbers[..x];
Span<int> zero_x = numbers[0..x];
Console.WriteLine($"\t{start_x[0]}..{start_x[^1]} is the same as {zero_x[0]}..{zero_x[^1]}");
Span<int> z_end = numbers[z..];
Span<int> z_zero = numbers[z..^0];
Console.WriteLine($"\t{z_end[0]}..{z_end[^1]} is the same as {z_zero[0]}..{z_zero[^1]}");
Sadece diziler dizinleri ve aralıkları desteklemez. Dizinleri ve aralıkları dize, Span<T>veya ReadOnlySpan<T>ile de kullanabilirsiniz.
Örtük aralık operatörü ifade dönüşümleri
Aralık işleci ifadesinin söz dizimini kullanırken, derleyici başlangıç ve bitiş değerlerini örtük olarak Index değerlerine dönüştürür ve bunlardan yeni bir Range örneği oluşturur. Aşağıdaki kod, aralık işleci ifadesinin söz diziminden örnek örtük dönüştürmeyi ve buna karşılık gelen açık alternatifi gösterir:
Range implicitRange = 3..^5;
Range explicitRange = new(
start: new Index(value: 3, fromEnd: false),
end: new Index(value: 5, fromEnd: true));
if (implicitRange.Equals(explicitRange))
{
Console.WriteLine(
$"The implicit range '{implicitRange}' equals the explicit range '{explicitRange}'");
}
// Sample output:
// The implicit range '3..^5' equals the explicit range '3..^5'
Önemli
Int32 öğesine dönüştürmelerde değeri negatif olduğunda bir ArgumentOutOfRangeException atan Index örtük dönüşümleri. Benzer şekilde, Index parametre negatif olduğunda ArgumentOutOfRangeException oluşturucu bir value oluşturur.
Dizinler ve aralıklar için tür desteği
Dizinler ve aralıklar, tek bir öğeye veya bir dizideki öğe aralığına erişmek için net, kısa söz dizimi sağlar. Dizin ifadesi genellikle bir dizinin öğelerinin türünü döndürür. Aralık ifadesi genellikle kaynak diziyle aynı dizi türünü döndürür.
Indeksleyici ile bir Index veya Range parametresini sağlayan herhangi bir tür, sırasıyla indeksleri veya aralıkları açıkça destekler. Tek bir Range parametresi alan dizin oluşturucu, örneğin System.Span<T> gibi farklı bir dizi türü döndürebilir.
Önemli
Aralık işlecini kullanan kodun performansı, sıra işleneninin türüne bağlıdır.
Aralık işlecinin zaman karmaşıklığı sıra türüne bağlıdır. Örneğin, dizi bir string veya diziyse, sonuç girişin belirtilen bölümünün bir kopyasıdır, bu nedenle zaman karmaşıklığı O(N) olur (burada N aralığın uzunluğudur). Öte yandan, System.Span<T> ya da System.Memory<T> ise, sonuç aynı arka depoya başvurur; başka bir deyişle kopyalama yoktur ve işlem O(1)'dir.
Bu, zaman karmaşıklığının yanı sıra ek ayırmalara ve kopyalara neden olarak performansı etkiler. Performansa duyarlı kodda, aralık işleci bunlar için ayırmadığından sıra türü olarak Span<T> veya Memory<T> kullanmayı göz önünde bulundurun.
Tür, ulaşılabilir bir alıcıya ve dönüş türü int olan veya Length adında bir özelliğe sahipse Count. Dizinleri veya aralıkları açıkça desteklemeyen sayılabilir bir tür, bunlar için örtük bir destek sağlayabilir. Daha fazla bilgi için özellik teklifi notununÖrtük Dizin desteği ve Örtük Aralık desteği bölümlerine bakın. Örtük aralık desteği kullanan aralıklar, kaynak diziyle aynı dizi türünü döndürür.
Örneğin, aşağıdaki .NET türleri hem dizinleri hem de aralıkları destekler: String, Span<T>ve ReadOnlySpan<T>. dizinleri List<T> destekler ancak aralıkları desteklemez.
Array daha fazla nüanslı davranışa sahiptir. Tek boyutlu diziler hem dizinleri hem de aralıkları destekler. Çok boyutlu diziler dizin oluşturucuları veya aralıkları desteklemez. Çok boyutlu bir dizinin dizin oluşturucusunun tek bir parametre değil, birden çok parametresi vardır. Dizi dizisi olarak da adlandırılan pürüzlü diziler hem aralıkları hem de dizin oluşturucuları destekler. Aşağıdaki örnek, düzensiz bir dizinin dikdörtgen alt bölümünün nasıl tekrar edileceğini göstermektedir. İlk ve son üç satırı ve seçilen her satırdaki ilk ve son iki sütunu hariç tutarak ortadaki bölümü yineler:
int[][] jagged =
[
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[10,11,12,13,14,15,16,17,18,19],
[20,21,22,23,24,25,26,27,28,29],
[30,31,32,33,34,35,36,37,38,39],
[40,41,42,43,44,45,46,47,48,49],
[50,51,52,53,54,55,56,57,58,59],
[60,61,62,63,64,65,66,67,68,69],
[70,71,72,73,74,75,76,77,78,79],
[80,81,82,83,84,85,86,87,88,89],
[90,91,92,93,94,95,96,97,98,99],
];
var selectedRows = jagged[3..^3];
foreach (var row in selectedRows)
{
var selectedColumns = row[2..^2];
foreach (var cell in selectedColumns)
{
Console.Write($"{cell}, ");
}
Console.WriteLine();
}
Her durumda, Array için aralık işleci döndürülen öğeleri depolamak için bir dizi ayırır.
Dizinler ve aralıklar için senaryolar
Daha büyük bir sıranın bir bölümünü analiz etmek istediğinizde genellikle aralıkları ve dizinleri kullanırsınız. Yeni söz dizimi, dizinin tam olarak hangi bölümünün dahil olduğunu okurken daha nettir. Yerel işlev MovingAverage bağımsız değişkeni olarak bir Range alır. Yöntemi daha sonra min, max ve average değerlerini hesaplarken yalnızca bu aralığı numaralandırır. Projenizde aşağıdaki kodu deneyin:
int[] sequence = Sequence(1000);
for(int start = 0; start < sequence.Length; start += 100)
{
Range r = start..(start+10);
var (min, max, average) = MovingAverage(sequence, r);
Console.WriteLine($"From {r.Start} to {r.End}: \tMin: {min},\tMax: {max},\tAverage: {average}");
}
for (int start = 0; start < sequence.Length; start += 100)
{
Range r = ^(start + 10)..^start;
var (min, max, average) = MovingAverage(sequence, r);
Console.WriteLine($"From {r.Start} to {r.End}: \tMin: {min},\tMax: {max},\tAverage: {average}");
}
(int min, int max, double average) MovingAverage(int[] subSequence, Range range) =>
(
subSequence[range].Min(),
subSequence[range].Max(),
subSequence[range].Average()
);
int[] Sequence(int count) => [..Enumerable.Range(0, count).Select(x => (int)(Math.Sqrt(x) * 100))];
Aralık Dizinleri ve Dizileriyle ilgili Bir Not
Bir diziden bir aralık alındığında, sonuç, referans edilmek yerine ilk diziden kopyalanan bir dizidir. Sonuçta elde edilen dizideki değerlerin değiştirilmesi, ilk dizideki değerleri değiştirmez.
Örneğin:
var arrayOfFiveItems = new[] { 1, 2, 3, 4, 5 };
var firstThreeItems = arrayOfFiveItems[..3]; // contains 1,2,3
firstThreeItems[0] = 11; // now contains 11,2,3
Console.WriteLine(string.Join(",", firstThreeItems));
Console.WriteLine(string.Join(",", arrayOfFiveItems));
// output:
// 11,2,3
// 1,2,3,4,5