2009-09-16 2 views
0

Извините за такой базовый вопрос о списках, но есть ли у нас эта функция в C#?Имеет ли список в C# поддержку нарезки, как в Python?

например. представьте себе этот список Python:

a = ['a','b,'c'] 
print a[0:1] 

>>>>['a','b'] 

Есть ли что-то вроде этого в C#? В настоящее время у меня есть необходимость проверить некоторые свойства объектов парами. Редактирование: пары всегда из двух: P

Представьте себе больше (питон) список:

a = ['a','a','b','c','d','d'] 

Мне нужно проверить, например if a[0] = a[1] и if a[1] = a[2] т.д.

Как это можно сделать в C#?

О, и последний вопрос: что такое тег (здесь), я могу использовать, чтобы отметить некоторые части моего сообщения в качестве кода?

+0

Почему вы не можете просто сделать: если (а [0] == a [1]) {...}? –

+1

Вы просто положили 4 пробела перед тем, что хотите отобразить в формате кода - кнопка «101010» сделает это для вас автоматически. –

+1

Точный дубликат: http://stackoverflow.com/questions/1301316/c-equivalent-of-python-slice-operation –

ответ

4

Вы можете использовать LINQ для создания лениво оцениваемой копии сегмента списка. То, что вы не можете обойти без дополнительного кода (насколько мне известно), принимает «вид» на произвольном IList<T>. Однако нет особых причин, почему это не может быть осуществимо. Вероятно, вы хотите, чтобы это был фиксированный размер (т. Е. Запретить изменения через Add/Remove), и вы также можете сделать его необязательным для чтения - в основном вы просто проксируете различные вызовы в исходный список.

Похоже, что это может быть очень полезно и довольно легко кодировать ... дайте мне знать, если вы хотите, чтобы я сделал это.

Из интереса, делает ли фрагмент Python подлинно представление или требуется его копия? Если позже вы измените содержимое исходного списка, это изменит содержимое среза? Если вам действительно нужна копия, решения LINQ с использованием Skip/Take/ToList абсолютно точны. Мне нравится идея дешевый вид на коллекцию, хотя ...

+0

Python, насколько я знаю Python только читает список.Он только скопирует список, если вы его прямо спрашиваете. В приведенном примере печать [0: 1] будет печатать только элементы этого диапазона. Если вы попросите распечатать a, он напечатает исходные элементы в списке, a b и c. Я хотел бы внести свой вклад в то, что Джон. Как мы можем связаться (более эффективным образом?) Спасибо за интерес! –

+0

@George: вы можете написать мне по электронной почте ([email protected]), но, честно говоря, я не думаю, что написание простой реализации займет много времени. Я, вероятно, поместил его в MiscUtil (http://pobox.com/~skeet/csharp/miscutil), если я не смогу придумать где-нибудь лучше. Попытаюсь найти какое-то время в выходные ... –

+0

@JonSkeet Я понимаю, что это довольно старый, но то, что вы описали выше, почти точно то, что я пытался создать, когда я столкнулся с этим вопросом. Я посмотрел на вашу последнюю версию MiscUtil ... Диапазон (который, по-видимому, относится к 2007 году), похоже, не то же самое. Это то, что вы когда-либо встречали, или новые версии .NET/C#/LINQ предоставили эту функцию другим способом? Спасибо – brichins

0

Я искал что-то вроде Python-Slicing в C#, не повезло. я, наконец, написал следующие строки расширения, чтобы имитировать питона нарезка:

static class StringExtensions 
{ 
    public static string Slice(this string input, string option) 
    { 
     var opts = option.Trim().Split(':').Select(s => s.Length > 0 ? (int?)int.Parse(s) : null).ToArray(); 
     if (opts.Length == 1) 
      return input[opts[0].Value].ToString();  // only one index 
     if (opts.Length == 2) 
      return Slice(input, opts[0], opts[1], 1);  // start and end 
     if (opts.Length == 3) 
      return Slice(input, opts[0], opts[1], opts[2]);  // start, end and step 
     throw new NotImplementedException(); 
    } 
    public static string Slice(this string input, int? start, int? end, int? step) 
    { 
     int len = input.Length; 
     if (!step.HasValue) 
      step = 1; 
     if (!start.HasValue) 
      start = (step.Value > 0) ? 0 : len-1; 
     else if (start < 0) 
      start += len; 
     if (!end.HasValue) 
      end = (step.Value > 0) ? len : -1; 
     else if (end < 0) 
      end += len; 
     string s = ""; 
     if (step < 0) 
      for (int i = start.Value; i > end.Value && i >= 0; i+=step.Value) 
       s += input[i]; 
     else 
      for (int i = start.Value; i < end.Value && i < len; i+=step.Value) 
       s += input[i]; 
     return s; 
    } 
} 

Примеры того, как использовать его:

"Hello".Slice("::-1"); // returns "olleH" 
"Hello".Slice("2:-1"); // returns "ll" 
Смежные вопросы