tags:

views:

84

answers:

3

The title says it all. :) I've been pondering this today, and I have a nagging feeling that this is something simple to implement and I'm just way out of it today, but anyway, here it is.

Instead of performing something like

// assume that I have a populated string[] myString
for (int i = 0; i < myString.Length; i++) {
    myString[i] = myString[i].Equals(string.Empty) ? "foo" : "bar;
}

I'd like to do something like PHP's array_map(), which (I think) would perform faster than explicit iteration.

Does C# have capacity for this kind of operation?

Thanks guys.

+1  A: 

No, because PHP arrays have nothing (!) in common with C# arrays. PHP arrays are hash tables, more like C#'s System.Collections.Hashtable or System.Collections.Generic.Dictionary<k, v>. Just realized this doesn't apply here, but it's important nonetheless.

Assuming I'm reading your pseudocode correctly though, you can do what you want with a LINQ query:

var result = from item in collection
             select item.Empty() ? "foo" : "bar";

I don't see why you'd think something like array_map would be faster than iteration though -- there's going to be iteration going on somewhere, no matter how you look at it. In PHP there's a speed boost from using the builtin function because PHP is interpreted, while the guts of array_map are compiled; but C# is a compiled language.

EDIT: After reading the docs, it looks like

var result = from item in array
             select Callback(item);

does essentially what you're looking for. Not sure how to shoehorn the "callback" bit into a function though.

Billy ONeal
The callback can just be a function that takes a string as a parameter and returns a string:private string Callback(string str) { return str.Equals(string.Empty) ? "foo" : "bar"; }
smoak
Yeah, I realized that bit about the iteration thing too, after I got a bit of a nap. Grrr. Thanks, +1 for a very thorough, researched answer. :)
Richard Neil Ilagan
@smoak: My lack of surety is how to get that callback into the function, not how to actually call the function or what semantics it has.
Billy ONeal
+3  A: 

With an extension method:

Func<string, string> mapFun = n => n.Equals(string.Empty) ? "foo" : "bar";
Enumerable<string> newNames = names.Select(mapFun);

You can also pass Func directly:

IEnumerable<string> newNames = names.Select(n => n.Equals(string.Empty) ? "foo" : "bar");

As seen on ideone. Here are a few other functions that are more or less equivalent:

PHP                C#
-------------------------------
array_map()       .Select()
array_filter()    .Where()
array_reduce()    .Aggregate()

MSDN Reference:

Enumerable Methods

NullUserException
Thanks. I may have to go with these. :) Much appreciated.
Richard Neil Ilagan
Note that this is equivalent to my answer, and [Microsoft recommends the Query syntax rather than the extension method syntax](http://msdn.microsoft.com/en-us/library/bb397947.aspx) used in this answer.
Billy ONeal
Instead of dogmatically following some recommendation, I prefer to decide individually what makes more sense. In this simple case here, a single line makes more sense than two lines. In more complex cases, especially when joins are involved, the query syntax is more readable.
Timwi
+1  A: 

Yes, just use one of the Enumerable extension methods. The equivalent of array_map() is called Select():

var result = array.Select(item => item == "" ? "foo" : "bar");

For operations like this, consider using IEnumerable<T> more than T[] (arrays), but if you already have an array, you can use it because T[] actually implements IEnumerable<T>.

As a bonus, the equivalent of array_filter() is called Where():

var nonEmpty = array.Where(item => item != "");

If you’re curious what other methods there are, there is a pretty good list with examples on MSDN.

Timwi
Note that this is equivalent to my answer, and [Microsoft recommends the Query syntax rather than the extension method syntax](http://msdn.microsoft.com/en-us/library/bb397947.aspx) used in this answer.
Billy ONeal
Instead of dogmatically following some recommendation, I prefer to decide individually what makes more sense. In these simple cases here, a single line makes more sense than two lines. In more complex cases, especially when joins are involved, the query syntax is more readable.
Timwi