For the reasons that I still do not understand (see this SO question) multidimensional arrays in CLR do not implement IEnumerable<T>. So the following does not compile:
var m = new int[2,2] {{1, 2}, {3, 4}};
var q = from e in m select e;
Then how come that this works just fine in VB.NET?
Sub Main()
Dim m(,) As Integer = {{1, 2}, {3, 4}}
Dim q = From e In m Select e
For Each i In q
Console.WriteLine(i)
Next
End Sub
Update:
The following code works because the C# compiler replaces the foreach with for loops to go through each dimension.
foreach(var e in m)
Console.WriteLine(e);
becomes
int[,] numArray3 = new int[,] { { 2, 2 }, { 3, 3 } };
int upperBound = numArray3.GetUpperBound(0);
int num4 = numArray3.GetUpperBound(1);
for (int i = numArray3.GetLowerBound(0); i <= upperBound; i++)
{
for (int j = numArray3.GetLowerBound(1); j <= num4; j++)
{
int num = numArray3[i, j];
Console.WriteLine(num);
}
}
The query works in VB.Net because it gets transformed into
IEnumerable<object> q = m.Cast<object>().Select<object, object>(o => o);
This works because you can call Cast<TResult>() on IEnumerable, which [*,*] implements.
The LINQ query doesn't work in C# because of the different approach the C# and VB.Net designers took. VB.Net takes a more hand holding approach and fixes your mistake and converts IEnumerable to IEnumerable<object> so it can be used.
In C#, you can simulate this by using
var q = from e in m.Cast<object>() select e;
There are two reasons they don't implement it natively in C#:
There's more than one way you could do it. Do you want each 'cell', or do you want each 'row'? And how do you define 'row': [], IEnumerable, other? What if there are more than two dimensions? As soon as they pick one way, an army of developers will tell them they should have done it a different way.
Thanks to iterator blocks and the yield keyword, it just so easy to implement your own that's specific to your need at the time. Of course, that's a C# construct, but it's not that much harder in VB.
The MSDN page for Array includes this:
Important Note:
In the .NET Framework version 2.0, the Array class implements the System.Collections.Generic.IList<T>, System.Collections.Generic.ICollection<T>, and System.Collections.Generic.IEnumerable<T> generic interfaces. The implementations are provided to arrays at run time,
Note the final words in the quote... it appears this generation does not happen for multi-dimensional arrays (so a documentation bug).
But as others have noted, what would T be? A good case can be made for T[] (or, these days with LINQ, IEnumerable<T>).
In the end, if you want to iterate all the array's members just stick with IEnumerable and Cast<T> extension. Otherwise easy to write your own.
Tip: instead of Cast<object>() use a typed range variable
Samuel stated:
In C#, you can simulate this by using
var q = from e in m.Cast<object>() select e;
// q is of type IEnumerable<object>
which is of course correct as far as mimicking VB in C# is concerned, but you would loose your type information. Instead, it is much easier and as it turns out, slightly better readable, to simply declare your range variable.
The following compiles, performs better, is type safe and does not loose type information:
var m = new int[2, 2] { { 1, 2 }, { 3, 4 } };
var q = from int e in m select e;
// q is of type IEnumerable<int>
In the original suggestion, you would have an IEnumerable<object>, using int e you change that into IEnumerable<int>, which has its advantages.
Related
I came across this dead end while trying to replace exceptions with either monad in c#.
Which leads me to think maybe it is not only language specific problem and more technique related missing feature.
Let me try to re-explain it more globally:
Given:
I have a 3rd party function( a function that is imported into my code and I have no access to) which receives a lazy list (c# IEnumerable,f# Seq...) and consume it
I Want:
To apply a function (LINQ select,map...) on the method's lazy list argument and will take each element of the list (lazily) and will do computation that might fail (throwing an exception or returning Error/Either).
The list to be consumed only "inside" the 3rd party function, I don't want to have to iterate over each element more then once.
With Exceptions/side effects this can be achieved easily with throwing exception from the select, map functions if error was found, this will stop the execution "inside" the 3rd party function. Then I could handle the exception outside of it (without the 3rd party being "aware" of my error handling), leaving the responsibility of the error handling to me.
While with Either it does not seem to be possible to get the same behavior without altering the 3rd party function. Intuitively I was trying to convert the list from the list of Eithers to Either of list, but this can be done only by consuming the list with functions. Like, aggregate or reduce (does Haskell's Sequence function act the same?).
All this leads me to the question are Maybes/Eithers or Error as return type, missing this behavior? Is there another way to achive the same thing with them?
As far as I can tell, Haskell Either is isomorphic to C#/Java-style exceptions, meaning that there's a translation from Either-based code to exception-based code, and vice versa. I'm not quite sure about this, though, as there may be some edge cases that I'm not aware of.
On the other hand, what I am sure of is that Either () a is isomorphic to Maybe a, so in the following, I'm going to stick with Either and ignore Maybe.
What you can do with exceptions in C#, you can also do with Either. The default in C# is to do no error handling1:
public IEnumerable<TResult> NoCatch<TResult, T>(
IEnumerable<T> source, Func<T, TResult> selector)
{
return source.Select(selector);
}
This will iterate over source until an exception happens. If no exception is thrown, it'll return IEnumerable<TResult>, but if an exception is thrown by selector, the entire method throws an exception as well. However, if elements of source were handled before an exception was thrown, and there were side-effects, that work remains done.
You can do the same in Haskell using sequence:
noCatch :: (Traversable t, Monad m) => (a -> m b) -> t a -> m (t b)
noCatch f = sequence . fmap f
If f is a function that returns Either, then it behaves in the same way:
*Answer> noCatch (\i -> if i < 10 then Right i else Left i) [1, 3, 5, 2]
Right [1,3,5,2]
*Answer> noCatch (\i -> if i < 10 then Right i else Left i) [1, 3, 5, 11, 2, 12]
Left 11
As you can see, if no Left value is ever returned, you get a Right case back, with all the mapped elements. If just one Left case is returned, you get that, and no further processing is done.
You could also imagine that you have a C# method that suppresses individual exceptions:
public IEnumerable<TResult> Suppress<TResult, T>(
IEnumerable<T> source, Func<T, TResult> selector)
{
foreach (var x in source)
try { yield selector(x) } catch {}
}
In Haskell, you could do this with Either:
filterRight :: (a -> Either e b) -> [a] -> [b]
filterRight f = rights . fmap f
This returns all the Right values, and ignores the Left values:
*Answer> filterRight (\i -> if i < 10 then Right i else Left i) [1, 3, 5, 11, 2, 12]
[1,3,5,2]
You can also write a method that processes the input until the first exception is thrown (if any):
public IEnumerable<TResult> ProcessUntilException<TResult, T>(
IEnumerable<T> source, Func<T, TResult> selector)
{
var exceptionHappened = false;
foreach (var x in source)
{
if (!exceptionHappened)
try { yield selector(x) } catch { exceptionHappened = true }
}
}
Again, you can achieve the same effect with Haskell:
takeWhileRight :: (a -> Either e b) -> [a] -> [Either e b]
takeWhileRight f = takeWhile isRight . fmap f
Examples:
*Answer> takeWhileRight (\i -> if i < 10 then Right i else Left i) [1, 3, 5, 11, 2, 12]
[Right 1,Right 3,Right 5]
*Answer> takeWhileRight (\i -> if i < 10 then Right i else Left i) [1, 3, 5, 2]
[Right 1,Right 3,Right 5,Right 2]
As you can see, however, both the C# examples and the Haskell examples need to be aware of the style of error-handling. While you can translate between the two styles, you can't use one with a method/function that expects the other.
If you have a third-party C# method that expects exception handling to be the way things are done, you can't pass it a sequence of Either values and hope that it can deal with it. You'd have to modify the method.
The converse isn't quite true, though, because exception-handling is built into C# (and Haskell as well, in fact); you can't really opt out of exception-handling in such languages. Imagine, however, a language that doesn't have built-in exception-handling (PureScript, perhaps?), and this would be true as well.
1 C# code may not compile.
I haven't got a compiler handy, but you may want to check my language-ext project. It's a functional base class library for C#.
For your needs it has:
Seq<A> which is a cons like lazy enumerable which will only evaluate once
Try<A> which is a delegate based monad which allows you to capture exceptions from third party code
Other common error handling monads: Option<A>, Either<L, R>, etc.
Bonus variants of those monads: OptionAsync<A>, TryOption<A>, TryAsync<A>, TryOptionAsync<A>
Ability to easily convert between those types: ToOption(), ToEither(), etc.
To apply a function (LINQ select,map...) on the method's lazy list argument and will take each element of the list (lazily) and will do computation that might fail (throwing an exception or returning Error/Either).
The list to be consumed only "inside" the 3rd party function, I don't want to have to iterate over each element more then once.
This is a little unclear of the actual goal. In language-ext you could do this:
using LanguageExt;
using static LanguageExt.Prelude;
// Dummy lazy enumerable
IEnumerable<int> Values()
{
for(int i = 0; i < 100; i++)
{
yield return UnreliableExternalFunc(i);
}
}
// Convert to a lazy sequence
Seq<int> seq = Seq(Values());
// Invoke external function that takes an IEnumerable
ExternalFunction(seq);
// Calling it again won't evaluate it twice
ExternalFunction(seq);
But if the Values() function threw an exception then it would end its yielding and would return. So you'd ideally have this:
// Dummy lazy enumerable
IEnumerable<Try<int>> Values()
{
for(int i = 0; i < 100; i++)
{
yield return Try(() => UnreliableExternalFunc(i));
}
}
Try is the constructor function for the Try monad. So your result would be a sequence of Try thunks. If you don't care about the exception you could convert it to an Option
// Dummy lazy enumerable
IEnumerable<Option<int>> Values()
{
for(int i = 0; i < 100; i++)
{
yield return Try(() => UnreliableExternalFunc(i)).ToOption();
}
}
The you could access all successes via:
var validValues = Values().Somes();
Or you could instead use Either:
// Dummy lazy enumerable
IEnumerable<Either<Exception, A>> Values()
{
for(int i = 0; i < 100; i++)
{
yield return Try(() => UnreliableExternalFunc(i)).ToEither();
}
}
Then you can get the valid results thus:
var seq = Seq(Values());
var validValues = seq.Rights();
And the errors:
var errors = seq.Lefts();
I converted it to a Seq so it doesn't evaluate twice.
One way or another, if you want to catch an exception that happens during the lazy evaluation of the enumerable, then you will need to wrap each value. If the exception can occur from the usage of the lazy value, but within a function then your only hope is to surround it with a Try:
// Convert to a lazy sequence
Seq<int> seq = Seq(Values()); // Values is back to returning IEnumerable<int>
// Invoke external function that takes an IEnumerable
var res = Try(() => ExternalFunction(seq)).IfFail(Seq<int>.Empty);
// Calling it again won't evaluate it twice
ExternalFunction(seq);
Intuitively I was trying to convert the list from the list of Eithers to Either of list, but this can be done only by consuming the list with functions. Like, aggregate or reduce (does Haskell's Sequence function act the same?).
You can do this in language-ext like so:
IEnumerable<Either<L, R>> listOfEithers = ...;
Either<L, IEnumerable<R>> eitherList = listOfEithers.Sequence();
Traverse is also supported:
Either<L, IEnumerable<R>> eitherList = listOfEithers.Traverse(x => map(x));
All combinations of monads support Sequence() and Traverse; so you could do it with a Seq<Either<L, R>> to get a Either<L, Seq<R>>, which would guarantee that the lazy sequence isn't invoked multiple times. Or a Seq<Try<A>> to get a Try<Seq<A>>, or any of the async variants for concurrent sequencing and traversal.
I'm not sure if any of this is covering what you're asking, the question is a bit broad. A more specific example would be useful.
Note: The point of this question is more from a curiosity perspective. I want to know out of curiosity whether it is even possible to transliterate the Haskell implementation into a functional C# equivalent.
So I've been learning myself Haskell for great good, and while solving Project Euler problems I ran into this beautiful Haskell Fibonacci implementation:
fibs :: [Integer]
fibs = 1:1:zipWith (+) fibs (tail fibs)
Of course I was tempted to write a C# version like this, so:
If I do this:
IEnumerable<int> fibs =
Enumerable.Zip(Enumerable.Concat(new int[] { 1, 1 }, fibs),
//^^error
fibs.Skip(1), (f, s) => f + s);
The error says use of unassigned local variable fibs.
So I went slightly imperative, while this compiles...
public static IEnumerable<int> Get()
{
return Enumerable.Zip(Enumerable.Concat(new int[] { 1, 1 }, Get()),
Get().Skip(1), (f, s) => f + s);
}
It breaks with a stack overflow exception! So I came here..
Questions:
Can anyone think of a functional C# equivalent that works?
I'd like some insight into why my solutions don't work.
The answer to your first question is: this is how to do it in C#:
using System;
using System.Collections.Generic;
using System.Linq;
class P
{
static IEnumerable<int> F()
{
yield return 1;
yield return 1;
foreach(int i in F().Zip(F().Skip(1), (a,b)=>a+b))
yield return i;
}
static void Main()
{
foreach(int i in F().Take(10))
Console.WriteLine(i);
}
}
The answer to your second question is: C# is eager by default, so your method has an unbounded recursion. Iterators that use yield however return an enumerator immediately, but do not construct each element until required; they are lazy. In Haskell everything is lazy automatically.
UPDATE: Commenter Yitz points out correctly that this is inefficient because, unlike Haskell, C# does not automatically memoize the results. It's not immediately clear to me how to fix it while keeping this bizarre recursive algorithm intact.
Of course you would never actually write fib like this in C# when it is so much easier to simply:
static IEnumerable<BigInteger> Fib()
{
BigInteger prev = 0;
BigInteger curr = 1;
while (true)
{
yield return curr;
var next = curr + prev;
prev = curr;
curr = next;
}
}
Unlike the C# version provided in Eric Lippert's answer, this F# version avoids repeated computation of elements and therefore has comparable efficiency with Haskell:
let rec fibs =
seq {
yield 1
yield 1
for (a, b) in Seq.zip fibs (Seq.skip 1 fibs) do
yield a + b
}
|> Seq.cache // this is critical for O(N)!
I have to warn you that I'm trying to fix your attempts, not to make a productive code.
Also, this solution is good to make our brains to explode, and maybe the computer also.
In your first snippet you tried to call recursive your field or local variable, that is not possible.Instead we can try with a lambda which could be more similar to that. We know from Church, that is also not possible, at least in the traditional way. Lambda expressions are unnamed; you can't call them by their name ( inside of the implementation ). But you can use the fixed point to do recursion. If you have a sane mind there is big chance of not knowing what is that, anyway you should give a try to this link before continuing with this.
fix :: (a -> a) -> a
fix f = f (fix f)
This will be the c# implementation (which is wrong)
A fix<A>(Func<A,A> f) {
return f(fix(f));
}
Why is wrong? Because fix(f) represents a beautiful stackoverflow. So we need to make it lazy:
A fix<A>(Func<Func<A>,A> f) {
return f(()=>fix(f));
}
Now is lazy! Actually you will see a lot of this in the following code.
In your second snippet and also in the first, you have the problem that the second argument to Enumerable.Concat is not lazy, and you will have stackoverflow exception, or infinite loop in the idealistic way. So let's make it lazy.
static IEnumerable<T> Concat<T>(IEnumerable<T> xs,Func<IEnumerable<T>> f) {
foreach (var x in xs)
yield return x;
foreach (var y in f())
yield return y;
}
Now, we have the whole "framework" to implement what you have tried in the functional way.
void play() {
Func<Func<Func<IEnumerable<int>>>, Func<IEnumerable<int>>> F = fibs => () =>
Concat(new int[] { 1, 1 },
()=> Enumerable.Zip (fibs()(), fibs()().Skip(1), (a,b)=> a + b));
//let's see some action
var n5 = fix(F)().Take(5).ToArray(); // instant
var n20 = fix(F)().Take(20).ToArray(); // relative fast
var n30 = fix(F)().Take(30).ToArray(); //this will take a lot of time to compute
//var n40 = fix(F)().Take(40).ToArray(); //!!! OutOfMemoryException
}
I know that the F signature is ugly like hell, but this is why languages like haskell exists, and even F#. C# is not made for this work to be done like this.
Now, the question is, why haskell can achieve something like this?Why? because whenever you say something like
a:: Int
a = 4
The most similar translation in C# is :
Func<Int> a = () => 4
Actually is much more involved in the haskell implementation, but this is the idea why similar method of solving problems looks so different if you want to write it in both languages
Here it is for Java, dependent on Functional Java:
final Stream<Integer> fibs = new F2<Integer, Integer, Stream<Integer>>() {
public Stream<Integer> f(final Integer a, final Integer b) {
return cons(a, curry().f(b).lazy().f(a + b));
}
}.f(1, 2);
For C#, you could depend on XSharpX
A take on Eric's answer that has Haskell equivalent performance, but still has other issues(thread safety, no way to free memory).
private static List<int> fibs = new List<int>(){1,1};
static IEnumerable<int> F()
{
foreach (var fib in fibs)
{
yield return fib;
}
int a, b;
while (true)
{
a = fibs.Last();
b = fibs[fibs.Count() - 2];
fibs.Add(a+b);
yield return a + b;
}
}
Translating from a Haskell environment to a .NET environment is much easier if you use F#, Microsoft's functional declarative language similar to Haskell.
I'm looking for an implementation of List<T>.IndexOf(List<T>). I've only found List<<T>.IndexOf(T) in the .NET class library.
I have a List longList and a List possibleSubList. I'd like to know if possibleSubList can be found as a sub-'string' within longList, and if so, the index into longList.
This is basically the same semantics as System.String.IndexOf. Anyone know what to call this or if there's a good implementation of it?
Pseudocode Examples:
{1, 2, 3, 9, 8, 7}.IndexOf({3, 9, 8}) = 2
{1, 2, 3, 9, 8, 7}.IndexOf({1, 2, 3, 9, 8, 7}) = 0
{1, 2, 3, 9, 8, 7}.IndexOf({2, 9}) = -1 (not found)
Clarification: I already have a straightforward implementation of this (two nested for loops), but my lists are rather long, and this is in a performance sensitive area. I'm hoping to find a more efficient implementation than my ~O(m*n).
Linear Z-Indexing is probably one of the fastest sublist searching algorithm out there today where the pattern is the same and corpus is dynamic, with a true O(n) complexity (with small alphabets, it performs exceptionally better than you might expect from O(n) as ZIndexing provides plenty of opportunities to skip indexes):
I wrote my implementation in a genetics algorithms class under the guidance of Shaojie Zhang from the University of Central Florida. I've adapted the algorithms to C#, and specifically to use generic IList<T>, if you decide to use it, please give credit. The research for these techniques are available here, and specifically, look at the lecture notes here.
At any rate, I've made the code available here
Look inside of TestZIndexing.cs for examples of how to perform searches (in this case on character sequences, but using generics you should be able to use anything with an equality operator).
The usage is simple:
IEnumerable<int> LinearZIndexer.FindZ<T>(
IList<T> patternSequence, IList<T> sourceSequence, bool bMatchFirstOnly)
where T: IComparable;
And, as some DNA is circular, I have a circular variant:
IEnumerable<int> LinearZIndexer.FindZCircular<T>(
IList<T> patternSequence, IList<T> sourceSequence, bool bMatchFirstOnly)
where T: IComparable;
Let's do it even faster: Suffix Trees
Alternatively, if you want to get even better performance than O(n), you can get O(m), where m is the size of the pattern list, by using a Suffix Tree. This works when the pattern changes and the corpus stays the same (the opposite of the previous case). Look inside the same library I contributed for TestSuffixTree.cs. The only difference here is that you must build the Suffix Tree ahead of time, so it is definitely for multiple pattern searches against a large corpus, but I provide an O(n) and Space(n) algorithm for building that suffix tree.
The calls are equally simple, and again, can use anything that provides an IComparable:
string strTest = "bananabananaorangebananaorangebananabananabananaban";
string[] strFind = {"banana", "orange", "ban"};
// I use char, but you can use any class or primitive that
// supports IComparable
var tree = new SuffixTree<char>();
tree.BuildTree(strTest.ToCharArray());
var results = tree.Find(str.ToCharArray());
foreach(var r in results) Console.WriteLine(r);
Enjoy.
Use the string search algorithm: (psuedo code)
findsubstring(list<T> s, list<T> m){
for(int i=0; i<s.length;++i)
for(int j=0; j<m.length;++j)
if(s[i] != s[j])
break;
if(j==m.length-1)
return i;
return -1;
}
I think your use of the word 'sub-string' was a little misleading. I believe you are trying to see whether a larger list contains a sub-sequence of elements that matches the entire sequence of elements from another list. This is an extension method that should do what you want it to do, if I understand what you want correctly:
public static int IndexOfSequence<T>(this IEnumerable<T> longL, IEnumerable<T> subL)
{
var longList = longL.ToList();
var subList = subL.ToList();
int longCount = longList.Count;
int subCount = subList.Count;
if (subCount > longCount)
{
return -1;
}
int numTries = longCount - subCount + 1;
for (int i = 0; i < numTries; i++)
{
var newList = new List<T>(longList.Skip(i).Take(subCount));
if (newList.SequenceEqual(subList))
{
return i;
}
}
return -1;
}
Then you can use it like:
int index = longList.IndexOfSequence(possibleSubList);
I see this Array.ConvertAll method, but it requires a Converter as an argument. I don't see why I need a converter, when I've already defined an implicit one in my class:
public static implicit operator Vec2(PointF p)
{
return new Vec2(p.X, p.Y);
}
I'm trying to cast an array of PointFs to an array of Vec2s. Is there a nice way to do this? Or should I just suck it up and write (another) converter or loop over the elements?
The proposed LINQ solution using Cast/'Select' is fine, but since you know you are working with an array here, using ConvertAll is rather more efficienct, and just as simple.
var newArray = Array.ConvertAll(array, item => (NewType)item);
Using ConvertAll means
a) the array is only iterated over once,
b) the operation is more optimised for arrays (does not use IEnumerator<T>).
Don't let the Converter<TInput, TOutput> type confuse you - it is just a simple delegate, and thus you can pass a lambda expression for it, as shown above.
As an update to this old question, you can now do:
myArray.Cast<Vec2>().ToArray();
where myArray contains the source objects, and Vec2 is the type you want to cast to.
Cast doesn't consider user defined implicit conversions so you can't cast the array like that. You can use select instead:
myArray.Select(p => (Vec2)p).ToArray();
Or write a converter:
Array.ConvertAll(points, (p => (Vec2)p));
The latter is probably more efficient as the size of the result is known in advance.
The most efficient way is:
class A { };
class B : A { };
A[] a = new A[9];
B[] b = a as B[];
This is an answer related to a bounty question asked by #user366312 and not to the original question.
What would be the solution in the case of .NET Framework 2.0?
As far as I know, LINQ was introduced to the.NET framework with version 3.5 back in 2007. So this means it is not possible to use LINQ in .NET Framework 2.0.
Therefore I would use just a regular for-loop and cast each element in the array.
Something like this without testing it:
var newArray = new NewType[myArray.Length];
for (var i = 0; i < myArray.Length; i++)
{
newArray[i] = (NewType)myArray[i];
}
You can wrap it up in a method like:
public static NewType[] ConvertAll(Vec2[] myArray)
{
var newArray = new NewType[myArray.Length];
for (var i = 0; i < myArray.Length; i++)
{
newArray[i] = (NewType)myArray[i];
}
return newArray;
}
And use it
var newArray = ConvertAll(myArray);
int z = 1;
double result = Math.Log(z); //works
However trying to do the same thing with an array of numbers doesn't work:
int[] z = new [] {1,2,3,4};
double[] result = Math.Log(z); //Syntax 1 - error CS1503: Argument '1': cannot convert from 'int[]' to 'double'
double[] result = z.Select(p => Log(p)).ToArray(); //Syntax 2 - OK
How can I make Syntax #1 work? Syntax #2 seems dirty to me.
No, there is not a cleaner way. The Syntax 2 use of Select() and a lambda expression to apply Math.Log() to each element is the idiomatic way of of doing this in C#.
int[] z = new [] {1,2,3,4};
double[] result = Array.ConvertAll(z, p => Log(p));
or
double Log(int i) { return Math.Log(i); }
int[] z = new[] { 1, 2, 3, 4 };
double[] result = Array.ConvertAll(z, Log);
For completeness, It should also be noted that one of the biggest stregths of Linq is the ability to extend it.
If this operation is something that you do a lot, it may well be a candidate to extend your IEnumerable with a Log function, this would be very simple
static class LogExtension
{
public static IEnumerable<Double> Log(this IEnumerable<int> list)
{
foreach (int i in list)
{
yield return Math.Log(i);
}
}
}
Then simply call it like...
IEnumerable<Double> logValues = myInts.AsEnumerable().Log();
You could encase the ugliness into a function:
private static double[] getLogForIntArray(int[] z)
{
double[] q = (double[])z.Select(p => Math.Log(p)).ToArray();
return q;
}
and call it for syntax 3 (and return it into something):
double[] q = getLogForIntArray(z); // Syntax 3
This looks the cleanest solution to me:-
double[] x = Array.ConvertAll(z, p => Math.Log(p));
It ought to be a better solution than select since ConvertAll knows up front how many elements there will be in the returned array. I'm not sure thats true of select, it could be if there some other compilier magic going on. However the above is cleaner because the convert intent is more clear.
In this code:
int[] z = new [] {1,2,3,4};
double[] result = z.Select(p => Log(p)).ToArray();
Most, if not all, of the "cruft" you see is due to the use of arrays, when the question title reads "Is there a cleaner syntax for applying an operation to each element of a sequence?"
In .NET 3.0, a "sequence" is encapsulated with the IEnumerable<> interface.
Using this, you end up with much cleaner code:
IEnumerable<int> z = new[] {1, 2, 3, 4};
IEnumerable<double> result = z.Select(i => Math.Log(i));
Throw in the use of implicit typing through the var keywork and things are very clear indeed:
var z = new[] {1, 2, 3, 4};
var result = z.Select(i => Math.Log(i));
Generally, you'll find the new features of C# 3.0 (especially LINQ) play most nicely when you use List<> instead of Arrays.
If you have code that is already array based, I'd suggest adding overloads to your API that accept IEnumerable instead of int[], allowing the consuming code to use modern language features.
Not quite sure what you're asking, but...
You could provide an index into the array.
for (int i = 0; i < z.Length; i++)
{
Math.Log(z[i]);
}
Though I see no point in not retaining the value of the calculation?
Edit
You might have to use the double data type as that is what math.log returns
static void Process()
{
double[] test = { 1, 2, 3, 4 };
double[] answer = new double[test.Length];
for (int i = 0; i < test.Length; i++)
{
answer[i] = Math.Log(test[i]);
}
}