C# element-wise difference between two lists of numbers - c#

Assume
List<int> diff(List<int> a, List<int> b)
{
// assume same length lists
List<int> diff= new List<int>(a.Count);
for (int i=0; i<diff.Count; ++i)
{
diff[i] = a[i] - b[i];
}
return diff;
}
I would like to have some kind of one-liner do the same, or something that uses a lambda, rather than re-writing all the boilerplate.
for instance, in python, this would be either
[ai-bi for ai,bi in zip(a,b)]
or even
np.array(a) - np.array(b)
Is there a nice way to write this in C#? All my searches find ways to remove or add list elements, but nothing about element-wise actions.

Linq has a Zip method as well:
var diff = a.Zip(b, (ai, bi) => ai - bi);
Note that one potential bug in your code is if b has fewer elements than a then you'd get an exception when you try to access an element outside the range of b. Zip will only return items as long as both collections have items, which is effectively the shorter of the two collection lengths.

Related

C# - Creating a recursive function to calculate the sum of a list. Is it possible using only the list as the only parameter?

So in my attempt to start learning c# one challenge I've come across is to create a recursive function that will calculate the sum of a list. I'm wondering if it's possible to do this using a list as the only argument of the function? Or would I need to apply an index size as well to work through the list?
int addRecursively(List<int> numList)
{
int total = numList[0];
if (numList.Count > 1)
{
numList.RemoveAt(0);
return total += addRecursively(numList);
}
Console.WriteLine(total);
return total;
}
List<int> numbers = new<List<int> {1,2,3,4,5,6,7,8};
addRecursively(numbers); //returns only the last element of whichever list I enter.
I was hoping by assigning the total to the first index of the list before deleting the first index of the list that when passed into the next instance of the function the index of each element in the list would move down one, allowing me to get each value in the list and totalling them up. However using the function will only ever return the last element of whichever list of integers I enter.
My thought process came from arrays and the idea of the shift method on an array in JS, removing the first element and bringing the whole thing down.
Am I attempting something stupid here? Is there another similar method I should be using or would I be better off simply including a list size as another parameter?
Thanks for your time
So in my attempt to start learning c# one challenge I've come across is to create a recursive function that will calculate the sum of a list. I'm wondering if it's possible to do this using a list as the only argument of the function? Or would I need to apply an index size as well to work through the list?
That's a great exercise for a beginner. However, you would never, ever do this with a List<int> in a realistic program. First, because you'd simply call .Sum() on it. But that's a cop-out; someone had to write Sum, and that person could be you.
The reason you would never do this recursively is List<T> is not a recursive data structure. As you note, every time you recurse there has to be something different. If there is not something different then you have an unbounded recursion!
That means you have to change one of the arguments, either by mutating it, if it is a reference type, or passing a different argument. Neither is correct in this case where the argument is a list.
For a list, you never want to mutate the list, by removing items, say. You don't own that list. The caller owns the list and it is rude to mutate it on them. When I call your method to sum a list, I don't want the list to be emptied; I might want to use it for something else.
And for a list, you never want to pass a different list in a recursion because constructing the new list from the old list is very expensive.
(There is also the issue of deep recursion; presumably we wish to sum lists of more than a thousand numbers, but that will eat up all the stack space if you go with a recursive solution; C# is not a guaranteed-tail-recursive language like F# is. However, for learning purposes let's ignore this issue and assume we are dealing with only small lists.)
Since both of the techniques for avoiding unbounded recursions are inapplicable, you must not write recursive algorithms on List<T> (or, as you note, you must pass an auxiliary parameter such as an index, and that's the thing you change). But your exercise is still valid; we just have to make it a better exercise by asking "what would we have to change to make a list that is amenable to recursion?"
We need to change two things: (1) make the list immutable, and (2) make it a recursively defined data structure. If it is immutable then you cannot change the caller's data by accident; it's unchangeable. And if it is a recursively defined data structure then there is a natural way to do recursion on it that is cheap.
So this is your new exercise:
An ImmutableList is either (1) empty, or (2) a single integer, called the "head", and an immutable list, called the "tail". Implement these in the manner of your choosing. (Abstract base class, interface implemented by multiple classes, single class that does the whole thing, whatever you think is best. Pay particular attention to the constructors.)
ImmutableList has three public read-only properties: bool IsEmpty, int Head and ImmutableList Tail. Implement them.
Now we can define int Sum(ImmutableList) as a recursive method: the base case is the sum of an empty list is zero; the inductive case is the sum of a non-empty list is the head plus the sum of the tail. Implement it; can you do it as a single line of code?
You will learn much more about C# and programming in a functional style with this exercise. Use iterative algorithms on List<T>, always; that is what it was designed for. Use recursion on data structures that are designed for recursion.
Bonus exercises:
Write Sum as an extension method, so that you can call myImmutableList.Sum().
Sum is a special case of an operation called Aggregate. It returns an integer, and takes three parameters: an immutable list, an integer called the accumulator, and a Func<int, int, int>. If the list is empty, the result is the accumulator. Otherwise, the result is the recursion on the tail and calling the function on the head and the accumulator. Write a recursive Aggregate; if you've done it correctly then int Sum(ImmutableList items) => Aggregate(items, 0, (acc, item) => acc + item); should be a correct implementation of Sum.
Genericize ImmutableList to ImmutableList<T>; genericize Aggregate to Aggregate<T, R> where T is the list element type and R is the accumulator type.
Try this way:
int addRecursively(List<int> lst)
{
if(lst.Count() == 0) return 0;
return lst.Take(1).First() + addRecursively(lst.Skip(1).ToList());
}
one more example:
static public int RecursiveSum(List<int> ints)
{
int nextIndex = 0;
if(ints.Count == 0)
return 0;
return ints[0] + RecursiveSum(ints.GetRange(++nextIndex, ints.Count - 1));
}
These are some ways to get the sum of integers in a list.
You don't need a recursive method, it spends more system resources when it isn't needed.
class Program
{
static void Main(string[] args)
{
List<int> numbers = new List<int>() { 1, 2, 3, 4, 5 };
int sum1 = numbers.Sum();
int sum2 = GetSum2(numbers);
int sum3 = GetSum3(numbers);
int sum4 = GetSum4(numbers);
}
private static int GetSum2(List<int> numbers)
{
int total = 0;
foreach (int number in numbers)
{
total += number;
}
return total;
}
private static int GetSum3(List<int> numbers)
{
int total = 0;
for (int i = 0; i < numbers.Count; i++)
{
total += numbers[i];
}
return total;
}
private static int GetSum4(List<int> numbers)
{
int total = 0;
numbers.ForEach((number) =>
{
total += number;
});
return total;
}
}

Sort one List<> based on another

Say I have
List<int> ages = new List<int>() { 8, 5, 3, 9, 2, 1, 7 };
List<int> marks = new List<int>() { 12, 17, 08, 15, 19, 02, 11 };
I can sort my marks by ages like this:
while (true)
{
bool swapped = false;
for (int i = 0; i < ages.Count - 1; i++)
if (ages[i] > ages[i + 1])
{
int tmp = ages[i];
ages[i] = ages[i + 1];
ages[i + 1] = tmp;
tmp = marks[i];
marks[i] = marks[i + 1];
marks[i + 1] = tmp;
swapped = true;
}
if (!swapped)
break;
}
Now I want to put this into a function that accepts any two lists. The first parameter will be the reference list, the numerical or comparable list. The second parameter will be the list containing the data.
For example:
public static void Sort<T>(List<T> RefList, List<T> DataList)
{
// sorting logic here...
}
There are a few problems:
First of all, T is almost certainly not the same type in RefList and DataList. RefList might be dates, integers, or doubles; whereas DataList is free to be absolutely anything. I need to be able to receive two, arbitrary generic types.
Secondly, I cannot seem to use the > operator with the T in this line:
if (ages[i] > ages[i + 1])
Perhaps my whole approach is wrong.
By the way, I have read responses to similar questions that suggest that the two lists should be combined into a single list of a compound data type. This isn't practical at all for my application. All I want to do is write a static function that somehow sorts one list based on the elements of another.
To sort one list the way you want you actually need to somehow keep references from items in first list to they weight/keys in the second list. No existing methods do that as you can't easily associate metadata with arbitrary values (i.e. if first list is list of int as in your case there is nothing to map to keys in second list). Your only reasonable option is to sort 2 lists at the same time and make association by index - again no existing classes to help.
It may be much easier to use solution that you reject. I.e. simply Zip and OrderBy, than recreate first list:
ages = ages
.Zip(marks, (a,m)=> new {age = a; mark = m;})
.OrderBy(v => v.mark)
.Select(v=>v.age)
.ToList();
Note (courtesy of phoog): if you need to do this type of sorting with Array there is Array.Sort that allows exactly this operatiion (see phoog's answer for details).
There's no framework method to do this with List<T>, but if you don't mind putting the data into two arrays, you can use one of the Array.Sort() overloads that takes two arrays as arguments. The first array is the keys, and the second is the values, so your code might look like this (leaving aside the step of getting arrays from the lists):
Array.Sort(ages, marks);
The specifics of getting the values into arrays and then back into lists would depend, among other things, on whether you need to end up with the same list sorted appropriately or whether it's okay to return a new list with the data in the desired order.
Use:
public static void Sort<TR, TD>(IList<TR> refList, IList<TD> dataList)
where TR : System.IComparable<TR>
where TD : System.IComparable<TD>
{
...
}
and then use:
refList[i].CompareTo(refList[i+1])
instead of the operators.
.Net numbers already implement IComparable, and you can use overloads that allow you to specify a different IComparable.
If I understand "I can sort my marks by ages like this:" properly,
I would like to suggest the below to eliminate much confusion.
struct Student{
int age;
int marks;
};
List<Student> students = {{8,12}, ...};
Now you can sort according to age and marks is accordingly sorted automatically.
If it is not possible, you need to fix the code as below.
First of all, T is almost certainly not the same type in RefList and DataList.
Then you need 2 parameters T1, T2. Just T implies the types are the same.
public static void Sort<RefType, DataType>(List<RefType> RefList, List<DataType> DataList)
{
You can also zip the two lists together as suggested by Mechanical Snail and explained in Looping through 2 Lists at once

What is the meaning of this code? (IEnumerable<int> query = from num in list)

What's the meaning of this:
IEnumerable<int> query = from num in list
where num < 3
select num;
Is this an object as IEnumerable<T>?
Can anyone please describe this?
You know normal method syntax, right? Things like list.Add(10). Some smart minds at Microsoft noted that there are similarities in many collections and lists. People might like to do things like selecting certain values and summing values that should work on all collections, without each and every collection providing a method for it.
Therefore they introduced extension methods, that are methods that are only defined once but can be applied to all objects of a certain type, such as collections. Examples are list.Where and list.Sum. To use extension methods, you have to add the namespace in which they are defined. The Where extension method takes a lambda expression which is executed on each and every element of the collection.
Lets say that you have some list of integers:
List<int> list = new List<int>();
list.Add(-1);
list.Add(0);
list.Add(1);
list.Add(2);
list.Add(3);
list.Add(4);
Then, where I previously would have to write the following code to get only those integers less than three:
List<int> query = new List<int>();
foreach(var nr in list)
{
if (nr < 3)
query.Add(nr);
}
Now, using extension methods, I can write it like this:
IEnumerable<int> query = list.Where(nr => nr < 3);
When enumerated, query will only return the integers from list that are less than three. These extension methods are part of LINQ, the Language Integrated Query.
However, to make LINQ easier to use, they devised a new syntax. With this new syntax, LINQ is easier to read and write.
IEnumerable<int> query = from nr in list
where nr < 3
select nr;
The compiler takes the new syntax and translates it to the previously mentioned code that includes the Where method. You see, its just syntactic sugar to make working with collections easier.
The IEnumerable<int> interface is a generic interface for any object that can be enumerated. The simplest form of enumeration is doing foreach on the object, and it returns all integers it contains, one by one. So, the LINQ query returns some object, but you don't know exactly the type. But you know it can be enumerated, and this makes it very useful.
It's a linq equivalent of say
IEnumerable<int> GetLessThanThree(IEnumerable<int> list)
{
foreach(int num in list)
{
if (num < 3)
{
yield return num
}
}
}
or if you haven't met yield yet
IEnumerable<int> GetLessThanThree(IEnumerable<int> list)
{
List<int> result = new List<int>();
foreach(int num in list)
{
if (num < 3)
{
result.Add(num);
}
}
return result;
}

Calling a list of methods in a random sequence?

I have a list of 10 methods. Now I want to call this methods in a random sequence. The sequence should be generated at runtime. Whats the best way to do this?
It is always astonishing to me the number of incorrect and inefficient answers one sees whenever anyone asks how to shuffle a list of things on StackOverflow. Here we have several examples of code which is brittle (because it assumes that key collisions are impossible when in fact they are merely rare) or slow for large lists. (In this case the problem is stated to be only ten elements, but when possible surely it is better to give a solution that scales to thousands of elements if doing so is not difficult.)
This is not a hard problem to solve correctly. The correct, fast way to do this is to create an array of actions, and then shuffle that array in-place using a Fisher-Yates Shuffle.
http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
Some things not to do:
Do not implement Fischer-Yates shuffle incorrectly. One sees more incorrect than correct implementations of this trivial algorithm. In particular, make sure you are choosing the random number from the correct range. Choosing it from the wrong range produces a biased shuffle.
If the shuffle algorithm must actually be unpredictable then use a source of randomness other than Random, which is only pseudo-random. Remember, Random only has 232 possible seeds, and therefore there are fewer than that many possible shuffles.
If you are going to be producing many shuffles in a short amount of time, do not create a new instance of Random every time. Save and re-use the old one, or use a different source of randomness entirely. Random chooses its seed based on the time; many Randoms created in close succession will produce the same sequence of "random" numbers.
Do not sort on a "random" GUID as your key. GUIDs are guaranteed to be unique. They are not guaranteed to be randomly ordered. It is perfectly legal for an implementation to spit out consecutive GUIDs.
Do not use a random function as a comparator and feed that to a sorting algorithm. Sort algorithms are permitted to do anything they please if the comparator is bad, including crashing, and including producing non-random results. As Microsoft recently found out, it is extremely embarrassing to get a simple algorithm like this wrong.
Do not use the input to random as the key to a dictionary, and then sort the dictionary. There is nothing stopping the randomness source from choosing the same key twice, and therefore either crashing your application with a duplicate key exception, or silently losing one of your methods.
Do not use the algorithm "Create two lists. Add the elements to the first list. Repeatedly move a random element from the first list to the second list, removing the element from the first list". If the list is O(n) to remove an item then this is an O(n2) algorithm.
Do not use the algorithm "Create two lists. Add the elements to the first list. Repeatedly move a random non-null element from the first list to the second list, setting the element in the first list to null." Also do not do this crazy equivalent of that algorithm.If there are lots of items in the list then this gets slower and slower as you start hitting more and more nulls.
New, short answer
Starting from where Ilya Kogan left off, totally correct after we had Eric Lippert find the bug:
var methods = new Action[10];
var rng = new Random();
var shuffled = methods.Select(m => Tuple.Create(rng.Next(), m))
.OrderBy(t => t.Item1).Select(t => t.Item2);
foreach (var action in shuffled) {
action();
}
Of course this is doing a lot behind the scenes. The method below should be much faster. But if LINQ is fast enough...
Old answer (much longer)
After stealing this code from here:
public static T[] RandomPermutation<T>(T[] array)
{
T[] retArray = new T[array.Length];
array.CopyTo(retArray, 0);
Random random = new Random();
for (int i = 0; i < array.Length; i += 1)
{
int swapIndex = random.Next(i, array.Length);
if (swapIndex != i)
{
T temp = retArray[i];
retArray[i] = retArray[swapIndex];
retArray[swapIndex] = temp;
}
}
return retArray;
}
the rest is easy:
var methods = new Action[10];
var perm = RandomPermutation(methods);
foreach (var method in perm)
{
// call the method
}
Have an array of delegates. Suppose you have this:
class YourClass {
public int YourFunction1(int x) { }
public int YourFunction2(int x) { }
public int YourFunction3(int x) { }
}
Now declare a delegate:
public delegate int MyDelegate(int x);
Now create an array of delegates:
MyDelegate delegates[] = new MyDelegate[10];
delegates[0] = new MyDelegate(YourClass.YourFunction1);
delegates[1] = new MyDelegate(YourClass.YourFunction2);
delegates[2] = new MyDelegate(YourClass.YourFunction3);
and now call it like this:
int result = delegates[randomIndex] (48);
You can create a shuffled collection of delegates, and then call all methods in the collection.
Here is an easy way of doing so using a dictionary. The keys of the dictionary are random numbers, and the values are delegates to your methods. When you iterate through the dictionary, it has the effect of shuffling.
var shuffledActions = actions.ToDictionary(
action => random.Next(),
action => action);
foreach (var pair in shuffledActions.OrderBy(item => item.Key))
{
pair.Value();
}
actions is an enumerable of your methods.
random is a of type Random.
Think that this is a list of objects and you want it to extract the objects randomly. You can get a random index using the Random.Next Method (always use current List.Count as parameter) and after that remove object from the list so it will not be drawn again.
When processing a list in a random order, the natural inclination is to shuffle a list.
Another approach is to just keep the list order, but randomly select and remove each item.
var actionList = new[]
{
new Action( () => CallMethodOne() ),
new Action( () => CallMethodTwo() ),
new Action( () => CallMethodThree() )
}.ToList();
var r = new Random();
while(actionList.Count() > 0) {
var index = r.Next(actionList.Count());
var action = actionList[index];
actionList.RemoveAt(index);
action();
}
I think:
Via reflection get Method Objects;
create an array of created Method Object;
generate random index (normalize range);
invoke method;
You can remove method from array to execute method one times.
Bye

Fastest way to compare two lists

I have a List (Foo) and I want to see if it's equal to another List (foo). What is the fastest way ?
From 3.5 onwards you may use a LINQ function for this:
List<string> l1 = new List<string> {"Hello", "World","How","Are","You"};
List<string> l2 = new List<string> {"Hello","World","How","Are","You"};
Console.WriteLine(l1.SequenceEqual(l2));
It also knows an overload to provide your own comparer
Here are the steps I would do:
Do an object.ReferenceEquals() if true, then return true.
Check the count, if not the same, return false.
Compare the elements one by one.
Here are some suggestions for the method:
Base the implementation on ICollection. This gives you the count, but doesn't restrict to specific collection type or contained type.
You can implement the method as an extension method to ICollection.
You will need to use the .Equals() for comparing the elements of the list.
Something like this:
public static bool CompareLists(List<int> l1, List<int> l2)
{
if (l1 == l2) return true;
if (l1.Count != l2.Count) return false;
for (int i=0; i<l1.Count; i++)
if (l1[i] != l2[i]) return false;
return true;
}
Some additional error checking (e.g. null-checks) might be required.
Something like this maybe using Match Action.
public static CompareList<T>(IList<T> obj1, IList<T> obj2, Action<T,T> match)
{
if (obj1.Count != obj2.Count) return false;
for (int i = 0; i < obj1.Count; i++)
{
if (obj2[i] != null && !match(obj1[i], obj2[i]))
return false;
}
}
Assuming you mean that you want to know if the CONTENTS are equal (not just the list's object reference.)
If you will be doing the equality check much more often than inserts then you may find it more efficient to generate a hashcode each time a value is inserted and compare hashcodes when doing the equality check. Note that you should consider if order is important or just that the lists have identical contents in any order.
Unless you are comparing very often I think this would usually be a waste.
One shortcut, that I didn't see mentioned, is that if you know how the lists were created, you may be able to join them into strings and compare directly.
For example...
In my case, I wanted to prompt the user for a list of words. I wanted to make sure that each word started with a letter, but after that, it could contain letters, numbers, or underscores. I'm particularly concerned that users will use dashes or start with numbers.
I use Regular Expressions to break it into 2 lists, and them join them back together and compare them as strings:
var testList = userInput.match(/[-|\w]+/g)
/*the above catches common errors:
using dash or starting with a numeric*/
listToUse = userInput.match(/[a-zA-Z]\w*/g)
if (listToUse.join(" ") != testList.join(" ")) {
return "the lists don't match"
Since I knew that neither list would contain spaces, and that the lists only contained simple strings, I could join them together with a space, and compare them.

Categories

Resources