tags:

views:

105

answers:

4

I use to use IDL and MatLab in college and now that I have been working for some years I miss the : notation for indexing into arrays. I.E.

arrray[1:5]

which would return an array from elements from 1 to 5. Another example is

stringVar.Split(")".ToCharArray())[1:*]

which would return an array of strings skipping over the first element.

Has anyone seen a way to shoe-horn : notation this into C#?

I have seen it in some interpreted languages and perl or pythin, can't remeber.

I wonder if this could be done with some operator overriding?

+2  A: 

Syntactically, there's nothing like this in C# and can't be done with operator overloading. Basically, per C# spec, the lexical analyzer will consider that a syntax error. You could use a third party custom preprocessor to make it work.

ArraySegment structure, however, semantically does a similar thing.

If you really love this stuff, consider looking at Python (or IronPython if you want it on .NET platform).

Mehrdad Afshari
A: 

There is no language syntax for this, but if you're using 3.5 you could use some IEnumerable extension methods to as you say "shoe-horn" it in:

int offset = 1;
int num = 5;
int[] array = new int[5];
var collection = array.Skip(offset).Take(num - offset);
Matt Kellogg
+4  A: 

This is not currently implemented in the BCL. The best way to add this on would be via an extension method. For instance, here's a quick and dirty example (not fully featured).

public static IEnumerable<T> GetRange<T>(this IEnumerable<T> enumerable, string range) {
  var arr = range.Split(':');
  var start = Int32.Parse(arr[0]);
  if ( arr[1] == "*" ) {
    return enmuerable.Skip(start);
  } else {
    var end = Int32.Parse(arr[1]);
    return enumerable.Skip(start).Take(end-start);
  }
}

Then you could do

strVar.GetRange("1:*");  // Skip first element take rest
strVar.GetRange("1:5");  // Skip first element next 5

Note: I'm not familiar with Matlab syntax at all so I'm not sure if I implemented it to the proper specs but hopefully it gets the general idea across.

JaredPar
I wonder how it's better than having an overloaded method with two parameters (and using some kind of constant in place of *).
Mehrdad Afshari
@Mehrdad, I think it's much better to do as you describe. Mainly I just wanted to demonstrate how one could implement such a feature if it was really important.
JaredPar
Nice! I went down the wrong path, I had activators and loops ... ugly. :)
JP Alioto
A: 

You could make your own two-dimensional index accessor, and have -1 represent *:

public object[] this[int x, int y]
{
    get {/* implement get logic here */}
    set {/* implement set logic here */}
}

You would use it like so:

object[] slice = myArray[1, 5];
object[] slice2 = myArray[1, -1];

I don't recommend it though... I believe you should conform yourself to the language you are using, not the other way around. There are methods and classes that do the same thing, see the other answers.

Blixt