I have a function in C# that is being called in F#, passing its parameters in a Microsoft.FSharp.Collections.List<object>.
How am I able to get the items from the F# List in the C# function?
EDIT
I have found a 'functional' style way to loop through them, and can pass them to a function as below to return C# System.Collection.List:
private static List<object> GetParams(Microsoft.FSharp.Collections.List<object> inparams)
{
List<object> parameters = new List<object>();
while (inparams != null)
{
parameters.Add(inparams.Head);
inparams = inparams.Tail;
}
return inparams;
}
EDIT AGAIN
The F# List, as was pointed out below, is Enumerable, so the above function can be replaced with the line;
new List<LiteralType>(parameters);
Is there any way, however, to reference an item in the F# list by index?
In general, avoid exposing F#-specific types (like the F# 'list' type) to other languages, because the experience is not all that great (as you can see).
An F# list is an IEnumerable, so you can create e.g. a System.Collections.Generic.List from it that way pretty easily.
There is no efficient indexing, as it's a singly-linked-list and so accessing an arbitrary element is O(n). If you do want that indexing, changing to another data structure is best.
In my C#-project I made extension methods to convert lists between C# and F# easily:
using System;
using System.Collections.Generic;
using Microsoft.FSharp.Collections;
public static class FSharpInteropExtensions {
public static FSharpList<TItemType> ToFSharplist<TItemType>(this IEnumerable<TItemType> myList)
{
return Microsoft.FSharp.Collections.ListModule.of_seq<TItemType>(myList);
}
public static IEnumerable<TItemType> ToEnumerable<TItemType>(this FSharpList<TItemType> fList)
{
return Microsoft.FSharp.Collections.SeqModule.of_list<TItemType>(fList);
}
}
Then use just like:
var lst = new List<int> { 1, 2, 3 }.ToFSharplist();
Answer to edited question:
Is there any way, however, to reference an item in the F# list by index?
I prefer f# over c# so here is the answer:
let public GetListElementAt i = mylist.[i]
returns an element (also for your C# code).
Related
Say I have a List<Objects>. I want to define the list of objects in one method, and use them in several others.
Here's the ways I've come up with and I'm looking for more or the correct way to do it.
You can define List<Objects> in every method that uses it.
Pros: It works. No chance of getting the wrong variable.
Cons: Code duplication.
You can use a private List<Objects> defined in the class and update it using (ref ListObjects)
Pros: I only have to define it once.
Cons: I feel like it's messy and bad practice.
You can pass List<Objects> as a parameter to the methods that use it.
Pros: Prevents code duplication
Cons: Have to make my populate functions return functions, and add parameters to my other methods. Possible conflicts with Events?
So that's what I've come up with. I'm really not sure which to use or if there's a better way to do this. Thoughts?
EDIT: Including some code as requested.
private List<MedicalPlan> medicalPlansList;
This is the list. It is a list that gets information from a database, here:
private void BindMedicalList()
{
medicalPlansList = new MedicalPlanRepository().RetrieveAll().Where(x => x.Year == year).ToList();
}
Then it's used to find objects in that list, such as
var result =
medicalPlansList.FirstOrDefault(
c => c.CoverageLevels.Any(p => p.Id == id));
This is, in general, how I'd do it. If you always use the same sequence of functions on a list, consider creating a chained function to handle that. You can also directly pass a function call inside one of the other function calls (as long as it returns a list), but that tends to look messy.
public List<int> DoSomethingWithList(List<int> list)
{
//do stuff
return list;
}
public List<int> DoSomethingElseWithList(List<int> list)
{
//do other stuff
return list;
}
public void SomeOtherFunction(string[] args)
{
var list = new List<int>() { 1, 2, 3, 4 }; //create list
list = DoSomethingWithList(list); //change list
list = DoSomethingElseWithList(list); //change list further
}
If you are working with an object that has a List<T> field, I'd do like this:
public class MyBigClass
{
private List<int> myList;
public MyBigClass()
{
//instantiate list in constructor
myList = new List<int>() { 1, 2, 3, 4 };
}
public void PublicListAdder(int val)
{
myList.Add(val);
}
private void PrivateListCleaner()
{
//remove all even numbers, just an example
myList.RemoveAll(x => x % 2 == 0);
}
}
You rarely need to use ref in C#, because it automatically handles pointers for you. You are (usually) not passing around a struct, you are passing around an object reference (which basically is a pointer).
Your #1 and #2 don't really make sense:
If you define a different list in every method that uses it, then you're using a different list each time. This is not sharing the list; this doesn't work. If you mean "call your method that creates the list from each method that uses it" then the same still applies: you're using a different list each time.
You don't need to use ref ListObjects to update a private member; a private member is just accessed by its name. This isn't bad practice; this is standard object-oriented practice.
Passing all required data into a method as parameters makes the method inherently more reusable as it reduces coupling to the class the method belongs to.
In short: #3 is good practice to an extent, as it increases the reusability of code. However, the use of #2 is fundamentally the reason we have Object-Oriented programming: to save you from repeatedly passing parameters into all your methods. This is exactly what private fields are designed for!
In most cases, I would probably go with Anders' answer. Depending on your situation, another way that is worth considering is to write extension methods for List.
namespace ExtensionMethods
{
public static class MyExtensions
{
public static object DoSomething(this List<T> list)
{
//do the something with list
}
}
}
And then you can use it like so:
var list = new List<int>();
list.DoSomething();
In that example, list is passed as the parameter to the extension method.
Usually a List<T> shouldn't belong to the state of an instance and exposed since it's mutable and you may change the state from the outside otherwise -unless your getter is designed to return a readonly list. Unless your design clearly allow such a possibility when it may occur. My reply doesn't really answer to your question is just a suggestion of good object oriented design. As someone already suggested much better than me you may pass a List back and forth each method and directly modify it.
I have a collection of anonymous class and I want to return an empty list of it.
What is the best readable expression to use?
I though of the following but I don't think they are readably enough:
var result = MyCollection.Take(0).ToList();
var result = MyCollection.Where(p => false).ToList();
Note: I don't want to empty the collection itself.
Any suggestion!
Whats about:
Enumerable.Empty<T>();
This returns an empty enumerable which is of type T. If you really want a List so you are free to do this:
Enumerable.Empty<T>().ToList<T>();
Actually, if you use a generic extension you don't even have to use any Linq to achieve this, you already have the anonymous type exposed through T
public static IList<T> GetEmptyList<T>(this IEnumerable<T> source)
{
return new List<T>();
}
var emp = MyCollection.GetEmptyList();
Given that your first suggestion works and should perform well - if readability is the only issue, why not create an extension method:
public static IList<T> CreateEmptyCopy(this IEnumerable<T> source)
{
return source.Take(0).ToList();
}
Now you can refactor your example to
var result = MyCollection.CreateEmptyCopy();
For performance reasons, you should stick with the first option you came up with.
The other one would iterate over the entire collection before returning an empty list.
Because the anonymous type there is no way, in source code, to create a list. There is, however, a way to create such list through reflection.
I have a ArrayList of type BookingData to List<BookingData> ?
I am using .net 2.0 so i cannot use arrayList.Cast<int>().ToList() , and I dont want to make here foreach loop , do you have better ideas ?
Thanks.
Do note that something is going to have to enumerate the array-list to construct the List<T>; its only a matter of whether you do it yourself or leave it to some other (framework / utility) method.
If this is a one-off, the solution that you wish to avoid (using an "in-place" foreach loop to do the conversion) is a perfectly reasonable option. If you find yourself doing this quite often, you could extract that out into a generic utility method, as in cdhowie's answer.
If your restriction is only that you must target .NET 2.0 (but can use C# 3), consider LINQBridge, which is a reimplementation of LINQ to Objects for .NET 2.0. This will let you use the Cast sample you've provided without change. It will work on C# 2 too, but you won't get the benefits of the extension-method syntax, better type-inference etc.
If you don't care about performance, nor do you want to go to the trouble of writing a utility method, you could use the in-built ArrayList.ToArray method to help out, by creating an intermediary array that plays well with List<T> (this isn't all that shorter than a foreach):
ArrayList arrayList = ...
// Create intermediary array
BookingData[] array = (BookingData[]) arrayList.ToArray(typeof(BookingData));
// Create the List<T> using the constructor that takes an IEnumerable<T>
List<BookingData> list = new List<BookingData>(array);
Finally, I would suggest, if possible to abandon using the obsolete non-generic collection-classes altogether.
Let's keep it simple:
// untested
List<T> ConvertArrayList<T>(ArrayList data)
{
List<T> result = new List<T> (data.Count);
foreach (T item in data)
result.Add(item);
return result;
}
...
List<BookingData> newList = ConvertArrayList<BookingData>(oldList);
Use this method:
public static List<T> ConvertToList<T>(ArrayList list)
{
if (list == null)
throw new ArgumentNullException("list");
List<T> newList = new List<T>(list.Count);
foreach (object obj in list)
newList.Add((T)obj);
// If you really don't want to use foreach:
// for (int i = 0; i < list.Count; i++)
// newList.Add((T)list[i]);
return newList;
}
Then you can:
List<BookingData> someList = ConvertToList<BookingData>(someArrayList);
You have to use foreach:
foreach (Object item in list1)
{
list2.Add((BookingData)item);
}
ToList() method is nothing but the Synthetic sugar for creating a List representation but internally it is also using loop to generate the list item.
so it is much cleaner and simpler to use a foreach iterator block.
I'm looking for a sorted data structure, that will be similar to the STL set(T).
I found SortedList, but it requires (key, val), I'm looking for something like List(string) - only sorted.
I found on the web Spring.Collections, but my framework does not recognize it.
Is there a simple SortedSet I could use in the regular basic framework?
Thanks,
Gal
You can do this with A System.Collections.Generic.Dictionary. Here's a good article: Dictionarys and sorting
Edit: The SortedDictionary seems even better.
A SortedSet < T > introduced in .NET 4.0 is what you are looking for, see MSDN here
Also List<T> can be sorted. It is not sorted by default, but you can sort it, even with custom sorting algorithms if you so wish.
There's nothing built into the framework other than SortedDictionary<K,V> and SortedList<K,V>.
The C5 Collections library has several sorted collections. One of the following should do the trick, depending on your exact requirements: SortedArray<T>, TreeBag<T> or TreeSet<T>.
There's also Power Collections, which provides OrderedBag<T> and OrderedSet<T> collections.
There is a System.Collections.SortedList or System.Collections.Generic.SortedList which is always sorted.
Or you can use the Array.Sort method to sort ar defined moments in time.
How about using a List<> and calling the Sort method?
Not an extension but try this
public class SortedList<T>: List<T>
{
public SortedList(): base()
{
}
public SortedList(IEnumerable<T> collection): base(collection)
{
}
public SortedList(int capacity)
: base(capacity)
{
}
public void AddSort(T item)
{
base.Add(item);
this.Sort();
}
}
It's only a starting point, but adds a new method AddSort.
An extension method would be used to alter the List<>.Add method and call the sort on the end of it.
Using extension method
Place the following in a namespace accessible by your code:
public static class ListExtension
{
public static void AddSort<T>(this List<T> list, T item)
{
list.Add(item);
list.Sort();
}
}
You can the use code such as:
List<int> newList = List<int>();
newList.AddSort(6);
newList.AddSort(4);
newList.AddSort(3);
And the values will be:
newList[0] == 3
newList[1] == 4
newList[3] == 6
You can also just use newList.Add and the list is then sorted when you call newList.AddSort
This question already has answers here:
LINQ equivalent of foreach for IEnumerable<T>
(22 answers)
Closed 6 years ago.
I have recently started off with LINQ and its amazing. I was wondering if LINQ would allow me to apply a function - any function - to all the elements of a collection, without using foreach. Something like python lambda functions.
For example if I have a int list, Can I add a constant to every element using LINQ
If i have a DB table, can i set a field for all records using LINQ.
I am using C#
A common way to approach this is to add your own ForEach generic method on IEnumerable<T>. Here's the one we've got in MoreLINQ:
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
source.ThrowIfNull("source");
action.ThrowIfNull("action");
foreach (T element in source)
{
action(element);
}
}
(Where ThrowIfNull is an extension method on any reference type, which does the obvious thing.)
It'll be interesting to see if this is part of .NET 4.0. It goes against the functional style of LINQ, but there's no doubt that a lot of people find it useful.
Once you've got that, you can write things like:
people.Where(person => person.Age < 21)
.ForEach(person => person.EjectFromBar());
The idiomatic way to do this with LINQ is to process the collection and return a new collection mapped in the fashion you want. For example, to add a constant to every element, you'd want something like
var newNumbers = oldNumbers.Select(i => i + 8);
Doing this in a functional way instead of mutating the state of your existing collection frequently helps you separate distinct operations in a way that's both easier to read and easier for the compiler to reason about.
If you're in a situation where you actually want to apply an action to every element of a collection (an action with side effects that are unrelated to the actual contents of the collection) that's not really what LINQ is best suited for, although you could fake it with Select (or write your own IEnumerable extension method, as many people have.) It's probably best to stick with a foreach loop in that case.
You could also consider going parallel, especially if you don't care about the sequence and more about getting something done for each item:
SomeIEnumerable<T>.AsParallel().ForAll( Action<T> / Delegate / Lambda )
For example:
var numbers = new[] { 1, 2, 3, 4, 5 };
numbers.AsParallel().ForAll( Console.WriteLine );
HTH.
haha, man, I just asked this question a few hours ago (kind of)...try this:
example:
someIntList.ForEach(i=>i+5);
ForEach() is one of the built in .NET methods
This will modify the list, as opposed to returning a new one.
Or you can hack it up.
Items.All(p => { p.IsAwesome = true; return true; });
For collections that do not support ForEach you can use static ForEach method in Parallel class:
var options = new ParallelOptions() { MaxDegreeOfParallelism = 1 };
Parallel.ForEach(_your_collection_, options, x => x._Your_Method_());
You can try something like
var foo = (from fooItems in context.footable select fooItems.fooID + 1);
Returns a list of id's +1, you can do the same with using a function to whatever you have in the select clause.
Update: As suggested from Jon Skeet this is a better version of the snippet of code I just posted:
var foo = context.footable.Select(foo => foo.fooID + 1);
I found some way to perform in on dictionary contain my custom class methods
foreach (var item in this.Values.Where(p => p.IsActive == false))
item.Refresh();
Where 'this' derived from : Dictionary<string, MyCustomClass>
class MyCustomClass
{
public void Refresh(){}
}