4

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?

1
  • Not related to your question, but... there is really no need for string.Empty (it’s a remnant from C# 1.0). Use "", it’s more readable. Also, when handling strings, you can use == instead of Equals: it’s exactly equivalent, and it’s also more readable. Commented Sep 1, 2010 at 23:01

3 Answers 3

6

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

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. I may have to go with these. :) Much appreciated.
Note that this is equivalent to my answer, and Microsoft recommends the Query syntax rather than the extension method syntax used in this answer.
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.
2

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.

2 Comments

Note that this is equivalent to my answer, and Microsoft recommends the Query syntax rather than the extension method syntax used in this answer.
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.
1

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.

3 Comments

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"; }
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. :)
@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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.