Contains method using Linq/Lambda - c#

This method finds different dates and adds to dates array. Is it possible to make this method with linq/lambda?
public static void FindDates(DateTime[] dates, LinkedList<Letter> L, out int counter)
{
counter = 0;
foreach (var let in L)
{
if (!dates.Contains(let.Date))
{
dates[counter] = let.Date;
counter++;
}
}
}

You need to change the prototype of the method, but you can do something like:
public static IReadOnlyList<DateTime> FindDates(IEnumerable<Letter> L)
{
return L.Select(l => l.Date).Distinct().ToList();
}
The value of counter can be retrieved easily by reading the Count property of the result list.
Overall, it's a good practice to avoid side-effects in methods as much as possible. Modifying an array passed as a parameter like you do is a good way to get bitten later.
Also, since the Linq extension methods are defined on IEnumerable<T>, we can change the parameter of the method to IEnumerable<Letter>. It'll work exactly the same with your LinkedList<Letter>, with the added benefit that it won't break if later you decide to use another collection type (such as List<Letter>)

Related

C# - List of Lists

I am coding in C# and I have a class with a property of type List<List<T>> that gets initialized in the constructor. The code is as follows:
public class MyMatrix<T>
{
private readonly List<List<T>> matrix;
public MyMatrix(int dimension)
{
this.matrix = new List<List<T>>();
for (int i = 0; i < dimension; i++)
{
List<T> subList = new List<T>();
this.matrix.Add(subList);
}
}
.....
The problem is that if I create a new object of type MyMatrix the sublists are empty so if I invoke the ToString() method of the class or any other method that returns the values contained in the sublists I get an OutOfOrder Exception as expected.
Get and Set methods are as follows:
public T Get(int row, int column)
{
return this.matrix[row][column];
}
public void Set(int row, int column, T value)
{
this.matrix[row].Insert(column, value);
}
If I initialize the sublists with a Set method then everything is fine obviously.
I can't change the constructor as it is up to the user of the class to initialize the sublists so it is not possible to know in advance what they are going to contain.
How would you manage the exceptions in the class methods or would you bother at all?
There are several approaches on managing exceptions in your case, and it depends on how you want to use the matrix class:
If you expect users to set values without initializing the row/column, then on the Set method I would just resize the list if necesary to accomodate the row/column arguments. You can always insert empty items in the list by using default(T) (this works both with value and reference objects). In this scenario, the Get method should check if the matrix coordinates exist and otherwise return default(T) so that no exceptions occurr.
If you expect users to always initialize the matrix, then just leave it as it is and throw exceptions. This is a clear hint that the application is misbehaving and the programmer must take care of this.
If you are trying to implement something like a Sparse Matrix, then using List<T> is not the best way and you should try another approach - for example using Dictionary<int, Dictionary<int, T>> or some sort of linked list. Anyway in this scenario, if you go for the Dictionary approach, you still need to take the same decisions as above (ie. throw if accessing a non existent coordinate or just return default(T))
What about C# 6.0?
public T Get(int row, int column)
{
return this.matrix[row]?[column] ?? default(T);
}

list property containing two types (string/int)

I need to have a property that will be an array that can hold both ints and strings.
if i set the property to an array of ints it should be ints so when I am searching through this array the search will be fast, and at odd times this property will also contain strings which the search will be slow.
Is there any other way other than the following to have a list that contain native types
two properties one for ints and one for strings
use List< object >
UPDATE:
The use-case is as follow. I have a database field [ReferenceNumber] that holds the values (integers and strings) and another field [SourceID] (used for other things) which can be used to determine if record holds an int or string.
I will be fetching collections of these records based on the source id, of course depending on what the source is, the list either will be integers or strings. Then I will go through this collection looking for certain reference numbers, if they exist not add them or they dont then add them. I will be pre-fetching a lot of records instead of hitting the database over and over.
so for example if i get a list for sourceid =1 that means they are ints and if searching i want the underline list to be int so the search will be fast. and if sourceid say is 2 which means they are strings and very rare its okay if the search is slow because those number of records are not that many and a performance hit on searching through strings is okay.
I will go through this collection looking for certain reference numbers, if they exist not add them or they dont then add them.
It sounds to me like you don't need a List<>, but rather a HashSet<>. Simply use a HashSet<object>, and Add() all the items, and the collection will ignore duplicate items. It will be super-fast, regardless of whether you're dealing with ints or strings.
On my computer, the following code shows that it takes about 50 milliseconds to populate an initial 400,000 unique strings in the hashset, and about 2 milliseconds to add an additional 10,000 random strings:
var sw = new Stopwatch();
var initial= Enumerable.Range(1, 400000).Select(i => i.ToString()).ToList();
sw.Start();
var set = new HashSet<object>(initial);
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
var random = new Random();
var additional = Enumerable.Range(1, 10000).Select(i => random.Next(1000000).ToString()).ToList();
sw.Restart();
foreach (var item in additional)
{
set.Add(item);
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
Also, in case it's important, HashSet<>s do retain order of insertion.
The only other thing I would suggest is a custom object that implements IComparable
class Multitype: IComparable
{
public int? Number { get; set; }
public string Words {get; set; }
public int CompareTo(object obj)
{
Multitype other = obj as Multitype;
if (Number != null && other != null && other.Number != null)
{
//...
}
else
{
//...
}
}
}
There will be some extra comparison steps between numbers, but not as much as string parsing.
Are you storing a ton of data, is that performance difference really going to matter?
It's possible to use generics if you implement them on the class. Not sure if this solves your problem. Would be interested to hear the real-world example of a property that can have different types.
class Foo<T>
{
public List<T> GenericList { get; set; }
public Foo()
{
this.GenericList = new List<T>();
}
}
If by "use List" you mean the object primitive or provided System.Object, that is an option, but I think it would behoove you to make your own wrapper object -- IntString or similar -- that would handle everything for you. It should implement IComparable, as the other gal mentioned.
You can increase the efficiency of sorting your object in collections by writing a CompareTo method that does exactly what you need it to. Writing a good CompareTo method is a whole can of worms in itself, so you should probably start a new question for that, if that's what you want.
If you're looking for a property that is strongly typed as a List<Int> or List<String> at instantiation, but can change afterwards, then you want an interface. IList exists, but won't help you, since that must also be strongly typed upon declaration. You should probably make something like IIntStringList that can only be one of List<Int> or List<String>.
Sorry this answer doesn't have that many details (I need to leave the office now), but I hope I've set you on the right track.

Passing list members into a function

How would I pass a list of values into a function, where the values are already stored in a list and the function isn't the same every time?
To explain, I've got a list of several different types of custom objects (A List<object> to make this work) and I want to pass those objects into a function. However, the function isn't always the same. I could have several different functions, and, assuming that List's contents will always match the function's input variables, I want to be able to pass the list's contents into my function.
The following code is an example of what might work, but for one flaw:
List<object> myListOfVariables = new List<object>();
myListOfVariables.Add("Hello, world!");
myListOfVariables.Add(10);
void SayHelloXTimes(string helloString, int x) {
for(int i = 0;i<x;i++) {
print(helloString)
}
}
SayHelloXTimes(myListOfVariables[0], myListOfVariables[1]);
Now, since I know my list will always contain the right amount of variables in the right positions, that would work, if I only had one function. But the problem is, I need to expand this so I could take apart my list and pass it into functions with different amounts of parameters.
For other reasons, I know my list will always have the right amount of variables in the right positions, so we don't need to worry about that. I'll also know the name of the function I need to pass my values into. I suppose I could do a load of if statements depending on the length of my list, like this:
if (myListOfVariables.Length == 2) {
SayHelloXTimes(myListOfVariables[0], myListOfVariables[1]);
}
else if (myListOfVariables.Length == 3) {
SayHelloXTimesForY(myListOfVariables[0], myListOfVariables[1], myListOfVariables[2]);
}
However, this (obviously) is really clunky code and I'd like to avoid it at all costs. Is there another solution to my problem? I know this is really confusing, but I did my best to explain it. If you're still confused as to what I'm trying to do, please let me know.
And no, this is not a homework problem. ;)
I think want you want to do can be done using reflection. Look at MethodBase.Invoke Method
All you have to do is add all the parameters in the order the function expects to an object array.
class Program
{
public static void SayHelloXTimes(string helloString, int x)
{
for (int i = 0; i < x; i++)
{
Console.WriteLine(helloString);
}
}
static void Main(string[] args)
{
MethodInfo Method = typeof(Program).GetMethod("SayHelloXTimes");
Method.Invoke(null, new object[] { "foo", 3 });
Console.ReadLine();
}
}
You want params:
void SayHelloXTimes(params string[] list) {
for(int i = 0;i<list.Length;i++) {
print(list[i])
}
}
SayHelloXTimes("Hi", "Hi", "Hi"); // legal
SayHelloXTimes("Hi"); // legal
SayHelloXTimes("Hi", "Hi", "Hi", "Hi", "Hi", "Hi"); // still legal
If this were my application, I would create a parameter class to hold the list values.
You could pass the list into the class' constructor and either extract it into class-local properties (since you know the positions) or you could expose the values as readonly property directly from the list.
You can then just pass an instance of the parameter class to each of the methods and not have to worry about the number of parameters to the methods.

Simple way to transpose data before passing to functions?

This is one of the hardest questions I've ever had to title here on SO. :) Although the title might not make sense, hopefully the question itself will.
Let's say I have a data structure like a Dictionary<string, List<double>>, and that I have functions that then take List<double>s as a parameter:
Dictionary<string, List<double>> candy_positions = new Dictionary<string, List<double>>();
candy_positions.Add( "Godiva", new List<double> { 1.0, 2.0, 4.0 });
EatCandy( candy_positions["Godiva"]);
...
But now I have decided that I don't want to do it this way. I want to replace my Dictionary with a List<CandyPositions>, where CandyPositions looks something like this:
public class CandyPositions
{
public double Sees;
public double Godiva;
public double Lindt;
}
However, I really would like to leave EatCandy() alone. Obviously, the problem is now that my data doesn't lend itself to be passed directly into the method. Instead, I have to do something lame like:
List<CandyPositions> candy_positions = new List<CandyPositions>();
...
var positions = from x in candy_positions select x.Godiva;
EatCandy( positions.ToList());
every time I want to call the method. I'd prefer to be able to do this in a more simple way, like:
EatCandy( candy_positions.GetPositionsFor( "Godiva"));
where the parameter "Godiva" matches the property name in the CandyPositions class.
After writing this question, I've realized that it isn't really about transposing data -- that part of it can be handled by writing an extension method. The part I don't know how to do is to pass in a property name, so that the extension method can take this and associate it with a class's property. I don't want to pass in a string, either, mainly because this will open the door for all sorts of runtime errors. I know how to make this work by passing "Godiva" to my extension method. What I really want to pass in is something akin to CandyPositions.Godiva instead.
This question is probably a little confusing, so in summary, I would accept the best of two types of answers:
Is there a better way to deal with transposing data, than to use an extension method + some way of accessing a property name?
Is there a way to specify the property that I want my extension method to retrieve, other than by a string?
My current extension method looks like this:
public static List<double> GetPositions( this List<CandyPositions> positions, string candy_name)
{
return (from x in positions select x.GetType().GetProperty(candy_name).GetValue(x, null)).Cast<double>().ToList();
}
Well, you could use:
public static List<double> GetPositions(this List<CandyPositions> positions,
Func<CandyPositions, double> projection)
{
return positions.Select(projection).ToList();
}
and call it with:
EatCandy(candyPositions.GetPositions(x => x.Godiva));
On the other hand, if you can change EatCandy to accept an IEnumerable<double> instead, you don't need the extra method - you can just use:
EatCandy(candyPositions.Select(x => x.Godiva));
without writing an extra method at all.
EDIT: If you need to iterate over two sequences at once, there are two options:
If you're using .NET 4, you can use the Zip extension method.
Otherwise, you can basically write your own:
using (var iterator1 = sequence1.GetEnumerator())
using (var iterator2 = sequence2.GetEnumerator())
{
while (iterator1.MoveNext() && iterator2.MoveNext())
{
var value1 = iterator1.Current;
var value2 = iterator2.Current;
// Use the values here
}
}

To Save a loop or to go with 2 methods - Convention vs. Performance

So everyone who cares about best practices in OOP and keeping code clean and in OOP knows that methods shouldn't be doing more than one thing. Methods are discrete units that do one thing and get out.
But here's a situation though where you could save some processing and improve performance if you were to combine 2 methods which are really doing 2 things into one and reuse the existing for loop that you already have in the first method:
private void RemoveDiscontinuedItems()
{
for(int s = 0; s < itemList.Count; s++)
{
if(!itemList[s].ItemIsOnSite)
{
RemoveItem(itemList[s].Id); // remove it from the DB
itemList.RemoveAt(s); // remove it from the collection
s--;
}
}
}
private void RemovePriceChangedItems()
{
for (int s = 0; s < itemList.Count; s++)
{
if(!PricingOptionIsValid(itemList[s]))
{
RemoveItem(itemList[s].Id); // remove it from the DB
itemList.RemoveAt(s); // remove it from the collection
s--;
}
}
}
These are called at page load. One removes items that are discontinued. The other removes items that have some pricing options that have changed and removes them from the same list.
Now if we were to stick with best practices, one could say that these are 2 completely independent purposes, thus we should not combine the logic in both these methods. That would then make the method be doing 2 things and I'd also have to come up with some f'd up name like RemoveDiscontinuedAndPriceChangeItems() or a generic name that doesn't tell me jack sh** like RemoveInvalidItemsFromList():
private void RemoveDiscontinuedItems()
{
for(int s = 0; s < itemsList.Count; s++)
{
if((!itemList[s].ItemIsOnSite))
{
RemoveItem(orderItemsSavedList[s].Id); // remove it from the DB
itemList.RemoveAt(s); // remove it from the collection
s--;
}
else if(!PricingOptionIsValid(itemList[s]))
{
RemoveItem(itemList[s].Id); // remove it from the DB
itemList.RemoveAt(s); // remove it from the collection
s--;
}
}
however thinking about the performance side, calling 2 methods that are looping through the same list to remove some items, would be more costly in cycles.
So, anyone against combining or are you for combining in this situation? Would like to hear some opinions out there.
Why not refactor so that each method performs a single action, rather then doing the loop. Then in the body of the loop call each method as needed.
Update
Here is a quick example based on your methods. Obviously the Loop method would be something different, in you application, however, I didn't have any other context for what you were doing. Also, I changed your for loop to a foreach.
private void Loop()
{
foreach (Item i in itemList)
{
if(!item.ItemIsOnSite)
{
RemoveDiscontinuedItems(i)
}
if(!item.PricingOptionIsValid)
{
RemovePriceChangedItems(i)
}
}
}
private void RemoveDiscontinuedItems(itemType item)
{
RemoveItem(item.Id); // remove it from the DB
item.Remove; // remove it from the collection
}
private void RemovePriceChangedItems(itemType item)
{
RemoveItem(item.Id); // remove it from the DB
item.Remove; // remove it from the collection
}
I think you're factoring is in the wrong place.
If you wrote it like this:
public void ConditionallyRemoveItems(Func<Item,bool> predicate)
{
for (int s=0; s < itemsList.Count; s++) {
if (predicate(itemList[s])) {
RemoveItem(orderItemsSavedList[s].Id);
itemList.RemoveAt(s);
s--;
}
}
}
// ...
ConditionallyRemoveItems(i => !i.ItemIsOnSize || !PricingOptionIsValid(i));
I also don't really like your style of messing with the loop variable - I prefer this style:
List<Item> itemsToRemove = new List<Items>();
foreach (Item i in itemList) {
if (predicate(i)) {
itemsToRemove.Add(i);
}
}
foreach (Item i in itemsToRemove)
itemList.Remove(i);
and if you don't like the performance of that, you can always do this:
List<Item> itemsToKeep = new List<Items>();
foreach (Item i in itemList) {
if (!predicate(i)) {
itemsToKeep.Add(i);
}
}
itemList = itemsToKeep;
A few things:
I don't see why you are looping forward when removing the items. You should be looping backwards and avoid the messy index manipulation when you perform a removal.
Thinking of this in terms of removing one item vs another based on an attribute is incorrect. You should see it as filtering the list. To that end, you should have a method that takes a Predicate<T> and then returns an IEnumerable<T> which you can then enumerate though (or an IList<T>, the same, if you want to just mutate the list). This way, you have the operation of filtering the list and the conditions separate (which is better separation IMO).
If you have access to LINQ, then there really is no reason to do this. You should be using a where filter on the original list, and if you want, factoring out the filtering logic into separate methods which will take the item and see if it should be returned. You can then construct your where clause (or Predicate<T> to pass to the Where extension method) from that.
this is probably the simplest way to do it, using a loop:
//counting backwards is easier when you are doing removals from a list
for( int i = lst.Count -1; i>= 0; i--)
{
if(condition1 || condition2)
{
RemoveFromDB(lst[i]);
lst.RemoveAt(i);
}
}
you can refactor that to use the functional methods provided by the framework:
var toRemove = lst.FindAll(
item => !PricingOptionIsValid(item) || !item.ItemIsOnSite()
);
toRemove.ForEach( item =>
{
RemoveFromDB(item.ID);
lst.Remove(item);
});
and you could write this without the toRemove variable, by chaining the ForEach onto the FindAll
There are several good suggestions on how to simplify and clarify your current code.
When considering performance always start with clean and concise code, don't worry about optimization until you have PROVEN a need to optimize.
Almost everything anyone writes in a high-level language:
a) COULD be faster.
b) is fast ENOUGH.
Seems like the standard approach if possible would be to make a function out of the loop contents, and a function that does both things:
doBothThings()
{
for(sharedLoop)
{
function1(loop counter);
function2(loop counter);
}
}
Gives you the performance but still separates the two pieces of functionality into separate functions. Obviously, not so simple if the two functions involve code before/after the loop.
Since both of your methods are removing items from your list, it doesn't necessarily make sense to combine the loops. You should determine if there's a significant performance difference between the two methods that you're using.
For example, if PricingOptionIsValid is an expensive operation (hits the database or whatever), you would want to call that in a second loop, after you've pruned as many items as possible with the first loop.
If the order of the tests doesn't matter, you should place the more likely branch first, and the less likely branch second. If ItemIsOnSite is false only 1% of the time, you're going to spend a lot of cycles skipping it.
You also might consider using an iterator instead of manipulating your loop variable. Either that or just find items to remove in the loop, then do another loop to remove them all.
In C# I would almost certainly not repeat the removal logic at all. Consider something like:
private delegate bool RemovalExpression(ItemType item);
private void RemoveItems(RemovalExpression shouldRemove)
{
for (int s = 0; s < itemList.Count; s++)
{
if (shouldRemove(itemList[s]))
{
RemoveItem(itemList[s].Id);
itemList.RemoveAt(s);
s--;
}
}
}
Which can be naturally used as:
RemoveItems(item => !item.ItemIsOnSite);
RemoveItems(item => !PricingOptionIsValid(item));
RemoveItems(item => (!item.ItemIsOnSite || !PricingOptionIsValid(item)));
etc.
Also from the sounds of it, you shouldn't be worrying about looping micro-optimizations at this point. If you don't have data that explicitly indicates that you're spending a disproportionate amount of your time in item removal, you have no way of knowing which construct will be "faster", nor any objective way of knowing whether your choice was worth the time investment, or a needless complication, or an outright pessimization of performance.
Therefore, write for maintainability; simple and clear and with no repetition of logic.
Use LINQ. And, aren't we past the 15 char min limit?
Do whatever makes sense, reduces complexity, and is easiest to maintain. Best practices are a guide.
Well if we're talking about proper OO, it's probably not a good idea put the responsibility of keeping itemList and whatever RemoveItem does in sync on the caller.
Personally I would use a list which has an OnRemove event you can hook into, and add RemoveItem as the event. This removes the need for the caller to remember to call RemoveItem.
This then makes the code much simpler, allowing you to use something like:
private void RemoveDiscontinuedItems()
{
itemList.RemoveAll(x => !x.ItemIsOnSite);
}
private void RemovePriceChangedItems()
{
itemList.RemoveAll(x => !PricingOptionIsValid(x));
}
The code is cleaner and the logic and purpose more obvious.
The performance obviously needn't be a concern unless it becomes a problem, though you must remember to test with extreme values (in this case a large list).
If you find that iterating through the list multiple times is actually a bottleneck then I'd propose something like this:
private bool IsDiscontinuedItem(Item item)
{
return !item.ItemIsOnSite;
}
private bool IsPriceChangedItem(Item item)
{
return !PricingOptionIsValid(item);
}
private bool IsInvalidItem(Item item)
{
return IsDiscontinuedItem(item) ||
IsPriceChangedItem(item);
}
private void RemoveInvalidItems()
{
itemList.RemoveAll(IsInvalidItem)
}
Here's my version:
private void RemoveDiscontinuedItems()
{
RemoveItems(item => item.ItemIsOnSite);
}
private void RemovePriceChangedItems()
{
RemoveItems(item => PricingOptionIsValid(item));
}
private void RemoveAll()
{
RemoveItems(item => item.ItemIsOnSite || PricingOptionIsValid(item));
}
private void RemoveItems(Predicate<Item> removeIfTruePredicate)
{
itemList.RemoveAll(
item =>
{
if(removeIfTruePredicate(item))
{
RemoveItem(item);
return true;
}
return false;
});
}
Note, this is based on your use of a mutable list. I'd be tempted to consider whether a mutable list is really needed. If not, I'd prefer to use a more functional style, and use a linq where clause to create a new list that excludes the items which need removing.
Given your desire for performance though, my guess is that RemoveAll (I'm assuming you're using List<T>) will be quicker than creation of a new list. Of course you'd really need to check this to be sure.

Categories