Home > Net >  How to parse a list quickly using a C# Method that only takes an item?
How to parse a list quickly using a C# Method that only takes an item?

Time:12-28

I am learning C# myself and I wonder if C# method can quickly parse a list of values just like Python does as below:

def myMethod(somevalue):
    return somevalue * 2

x = [1,2,3,4,5]
a = [myMethod(i) for i in x]

Currently I am trying to make a class that has a method that takes in a double. But what if x is a list?

  class myClass
  {
    public double somevalue;
    public myClass(double someValue)
    {
      somevalue = someValue;
    }
    
    public double myMethod()
    {
      return somevalue * 2;
    }
  }

myClass output = new myClass(x);
A = output.myMethod();

My question is, can C# create very concise codes that makes the Method takes in the list, loop through the list and gives out a list of results?

CodePudding user response:

Not a python expert but this:

def myMethod(somevalue):
    return somevalue * 2

x = [1,2,3,4,5]
a = [myMethod(i) for i in x]

Looks like it would be this in C#:

//either:
double TimesTwo(double d) => d * 2;          //a method declaration that is "expression bodied" style

//or:
double TimesTwo(double d) { return d * 2; }  //a method declaration that is "normal" style


void SomeOtherMethod(){                      //these statements can't just be floating around in a namespace like the method declarations above, they have to be inside some other method

    var x = new[] {1d,2,3,4,5};              //the first element is a double (1d), the others will be promoted from int to double without needing an explicit cast, the whole array x is a double[]
    var a = x.Select(TimesTwo).ToArray();

}

You can skip creating a separate method for the * 2 operation (the method above is called TimesTwo) and just put the logic of what you want inline:

    var x = new[] { 1d,2,3,4,5 };
    var a = x.Select(p => p * 2).ToArray();

The p => p * 2 is something like an "inline method" - we refer to them as lambdas; the input argument is called p and its type is inferred from the type of the collection that .Select is called on. In this case a double is inferred, because x is a double array

The return keyword is not specified in a single line lambda (which we refer to as an expression bodied something); the single line of code after the => (in both p => ... and TimesTwo(int i) => ...) is a statement that resolves to a value, and that value is implicitly returned. In this case the statement p => p * 2 multiplies input p by 2 and the result is returned automatically.

The result of the .Select method is an enumerable (specifically of type IEnumerable<double>, and the ToArray() method will enumerate it and turn it into an array. It is the calling of ToArray that causes p*2 to be invoked on every member, and ToArray collects all the results and outputs an array

All this code comes from extension methods in the System.Linq namespace, so your code needs using System.Linq; at the top


One important point, that may well bite at some time in the future; the code in the lambda within the Select is not performed if the enumerable output by the Select is not actually enumerated. If you had:

var enumerableThing = oneThousandThings.Select(p => SomeOperationThatTakesOneSecond(p));

It would execute near instantly; nothing in that line of code enumerates the resulting enumerable, no memory is allocated for a new array, no looping over collections of anything occurs, the operation that takes 1 second is not even called once let alone a thousand times.

If you later did something that actually enumerated the result, then the operation would take a thousand seconds:

var arr = enumerableThing.ToArray() //takes 1000s


foreach(var x in enumerableThing)  //would take 1000s to finish looping
  ...


int i = 500;                       
foreach(var x in enumerableThing){ //would take 500s, the enumeration quitting early after being half done
  i--;
  if(i == 0) break;
}

This enumerating could be done hours or days later; it's called deferred execution and is worth looking into further if you're not familiar with it

CodePudding user response:

You would use System.Linq.Enumerable.Where() to filter the List

var filtered = x.Where(y => myMethod(y)).ToList();

or Select to convert the list

var converted = x.Select(y => myMethod(y)).ToList();
  •  Tags:  
  • c#
  • Related