Shortest code to calculate list min/max in .NET - c#

I'd like something like
int minIndex = list.FindMin(delegate (MyClass a, MyClass b) {returns a.CompareTo(b);});
Is there a builtin way to do this in .NET?

Try looking at these:
Min
Max
As long as your class implements IComparable, all you have to do is:
List<MyClass> list = new List();
//add whatever you need to add
MyClass min = list.Min();
MyClass max = list.Max();

Well, if you can't use .NET 3.5, you could always sort the list and then return list[0]. It might not be the fastest way, but it's probably the shortest code, especially if your class already implements IComparable.
List<SomeClass> list = new List<SomeClass>();
// populate the list
// assume that SomeClass implements IComparable
list.Sort();
return list[0]; // min, or
return list[list.Count - 1]; // max
This also assumes, of course, that it doesn't matter which item you return if you have multiple items that are the minimum or maximum.
If your class doesn't implement IComparable, you can pass in an anonymous delegate, something like this:
list.Sort(delegate(SomeClass x, SomeClass y) { return string.Compare(x.Name, y.Name); });

You note that "I'm still in 2" - you might, then, want to look at LINQBridge. This is actually aimed at C# 3.0 and .NET 2.0, but you should be able to use it with C# 2.0 and .NET 2.0 - just you'll have to use the long-hand:
MyClass min = Enumerable.Min(list),
max = Enumerable.Max(list);
Of course, it will be easier if you can switch to C# 3.0 (still targetting .NET 2.0).
And if LINQBridge isn't an option, you can implement it yourself:
static void Main()
{
int[] data = { 3, 5, 1, 5, 5 };
int min = Min(data);
}
static T Min<T>(IEnumerable<T> values)
{
return Min<T>(values, Comparer<T>.Default);
}
static T Min<T>(IEnumerable<T> values, IComparer<T> comparer)
{
bool first = true;
T result = default(T);
foreach(T value in values) {
if(first)
{
result = value;
first = false;
}
else
{
if(comparer.Compare(result, value) > 0)
{
result = value;
}
}
}
return result;
}

Using Linq you have the Min() and Max() functions.
So you can do list.AsQueryable().Min();

Related

C# synchronize 2 lists of different types by time

I have 2 lists of different types. I think for now it doesn't matter what types that are.
Both types have an information about occurance which is in ticks (but can also be a DateTime).
What I want to do is, to synchronize these 2 lists by time so for example i can iterate through all elements in the order how they occured in time.
Example: // in this example List has elements called A_NUM or B_NUM depending on a type of list and number after '_' will represent order at which this elements/events occured
ListA = {A_2, A_3, A_5}
ListB = {B_1, B_4, B_6}
And the result after synchronization will be something like this:
ResultList = {B_1, A_2, A_3, B_4, A_5, B_6}
Is it somehow possible to make such mixed list? Or I have to create some auxiliary List or Dictionary which will tell me synchronized order of this 2 lists?
EDIT:
One list is a list of eye fixations. Fixation have a position, duration, ... and also occurance attributes.
Second list is a list of some changes of text, for example on line 12 column 3 there was a char 'x' added at some time t.
And I want to iterate through these 2 lists simultaneously. I mean at time t1 fixation occured at position x,y. At time t2 there was a text change at position u,v, so I want to iterate through these events in the order as they occured in time.
Note: YES both lists are sorted by time. It is a sequence of fixations and sequence of text changes.
Your question strongly suggests a merge sort as the basic implementation detail. You have two inputs, both sorted, and just want them merged together in sequence.
The main difficulty implied by your question is that you are trying to merge sequences of two completely unrelated types. Ordinarily, you'd merge sequences of the same type, and so could easily manipulate them together. Barring that, they'd at least share a base class or interface type, so that you could treat them as a single generalized type. But it seems, from your question, that this is not the case.
Given that, I think the most straight-forward approach is still to use a merge sort, but to provide a mechanism for the sort to access the relevant property (ticks, DateTime, whatever). The sort would return the merged sequences, in correct order, as the object type (i.e. the only base type common to both inputs) and the caller would then have to cast back to the individual types for whatever purpose.
Here's an example of what I mean:
private static IEnumerable<TBase> Merge<TBase, T1, T2, TValue>(
IEnumerable<T1> sequence1, IEnumerable<T2> sequence2,
Func<T1, TValue> valueSelector1, Func<T2, TValue> valueSelector2)
where T1 : TBase
where T2 : TBase
where TValue : IComparable<TValue>
{
IEnumerator<T1> enumerator1 = sequence1.GetEnumerator();
IEnumerator<T2> enumerator2 = sequence2.GetEnumerator();
bool notDone1 = enumerator1.MoveNext(),
notDone2 = enumerator2.MoveNext();
while (notDone1 && notDone2)
{
TValue value1 = valueSelector1(enumerator1.Current),
value2 = valueSelector2(enumerator2.Current);
if (value1.CompareTo(value2) <= 0)
{
yield return enumerator1.Current;
notDone1 = enumerator1.MoveNext();
}
else
{
yield return enumerator2.Current;
notDone2 = enumerator2.MoveNext();
}
}
while (notDone1)
{
yield return enumerator1.Current;
notDone1 = enumerator1.MoveNext();
}
while (notDone2)
{
yield return enumerator2.Current;
notDone2 = enumerator2.MoveNext();
}
}
Used like this:
class A
{
public int Value { get; }
public A(int value)
{
Value = value;
}
}
class B
{
public int Value { get; }
public B(int value)
{
Value = value;
}
}
static void Main(string[] args)
{
const int minCount = 5, maxCount = 15, maxValue = 50;
Random random = new Random();
int listACount = random.Next(minCount, maxCount),
listBCount = random.Next(minCount, maxCount);
A[] listA = RandomOrderedSequence(random, maxValue, listACount).Select(i => new A(i)).ToArray();
B[] listB = RandomOrderedSequence(random, maxValue, listBCount).Select(i => new B(i)).ToArray();
Console.WriteLine("listA: ");
Console.WriteLine(string.Join(", ", listA.Select(a => a.Value)));
Console.WriteLine("listB: ");
Console.WriteLine(string.Join(", ", listB.Select(b => b.Value)));
foreach (object o in Merge<object, A, B, int>(listA, listB, a => a.Value, b => b.Value))
{
A a = o as A;
if (a != null)
{
// Do something with object of type A
Console.WriteLine($"a.Value: {a.Value}");
}
else
{
// Must be a B. Do something with object of type B
B b = (B)o;
Console.WriteLine($"b.Value: {b.Value}");
}
}
}
static IEnumerable<int> RandomOrderedSequence(Random random, int max, int count)
{
return RandomSequence(random, max, count).OrderBy(i => i);
}
static IEnumerable<int> RandomSequence(Random random, int max, int count)
{
while (count-- > 0)
{
yield return random.Next(max);
}
}
In your case, you would of course replace types A and B with the types you're actually using, provide appropriate selectors, and then do whatever you like with each instance returned as the merged, in-order sequence.
Note that even if the types do turn out to share some common basis for which they can be compared and merged, I would still recommend a merge sort over simply concatenating and merging the result. The merge sort is a much more efficient way to merge already-ordered data into a single sequence of ordered data.
You need the lists to implement a common interface so they can be compared. For example:
public interface ISynchronizable
{
long GetTicks();
}
So you need to have the two object implement this, like so:
public class Fixation : ISynchronizable
{
public long GetTicks()
{
// get the ticks
}
// some other code
}
public class TextChange: ISynchronizable
{
public long GetTicks()
{
// get the ticks
}
// some other code
}
Then the result list would be created like this:
public List<ISynchronizable> list = new List<ISynchronizable>();
list.AddRange(fixationList);
list.AddRange(textChangeList);
resultList = list.OrderBy(e => e.GetTicks()).ToList();

GetHashCode() on byte[] array

What does GetHashCode() calculate when invoked on the byte[] array?
The 2 data arrays with equal content do not provide the same hash.
Arrays in .NET don't override Equals or GetHashCode, so the value you'll get is basically based on reference equality (i.e. the default implementation in Object) - for value equality you'll need to roll your own code (or find some from a third party). You may want to implement IEqualityComparer<byte[]> if you're trying to use byte arrays as keys in a dictionary etc.
EDIT: Here's a reusable array equality comparer which should be fine so long as the array element handles equality appropriately. Note that you mustn't mutate the array after using it as a key in a dictionary, otherwise you won't be able to find it again - even with the same reference.
using System;
using System.Collections.Generic;
public sealed class ArrayEqualityComparer<T> : IEqualityComparer<T[]>
{
// You could make this a per-instance field with a constructor parameter
private static readonly EqualityComparer<T> elementComparer
= EqualityComparer<T>.Default;
public bool Equals(T[] first, T[] second)
{
if (first == second)
{
return true;
}
if (first == null || second == null)
{
return false;
}
if (first.Length != second.Length)
{
return false;
}
for (int i = 0; i < first.Length; i++)
{
if (!elementComparer.Equals(first[i], second[i]))
{
return false;
}
}
return true;
}
public int GetHashCode(T[] array)
{
unchecked
{
if (array == null)
{
return 0;
}
int hash = 17;
foreach (T element in array)
{
hash = hash * 31 + elementComparer.GetHashCode(element);
}
return hash;
}
}
}
class Test
{
static void Main()
{
byte[] x = { 1, 2, 3 };
byte[] y = { 1, 2, 3 };
byte[] z = { 4, 5, 6 };
var comparer = new ArrayEqualityComparer<byte>();
Console.WriteLine(comparer.GetHashCode(x));
Console.WriteLine(comparer.GetHashCode(y));
Console.WriteLine(comparer.GetHashCode(z));
Console.WriteLine(comparer.Equals(x, y));
Console.WriteLine(comparer.Equals(x, z));
}
}
Like other non-primitive built-in types, it just returns something arbitrary. It definitely doesn't try to hash the contents of the array. See this answer.
Simple solution
public static int GetHashFromBytes(byte[] bytes)
{
return new BigInteger(bytes).GetHashCode();
}
byte[] inherits GetHashCode() from object, it doesn't override it. So what you get is basically object's implementation.
If you are using .NET 6 or at least .NET Core 2.1, you can write less codes and achieve better performance with System.HashCode struct.
Using the method HashCode.AddBytes() which available from .NET 6:
public int GetHashCode(byte[] value)
{
var hash = new HashCode();
hash.AddBytes(value);
return hash.ToHashCode();
}
Using the method HashCode.Add which available from .NET Core 2.1:
public int GetHashCode(byte[] value) =>
value.Aggregate(new HashCode(), (hash, i) => {
hash.Add(i);
return hash;
}).ToHashCode();
Note in the document of HashCode.AddBytes() it says:
This method does not guarantee that the result of adding a span of bytes will match the result of adding the same bytes individually.
In this sharplab demo they are just output same result, but this might be varying from .NET version or runtime environment.
If it's not the same instance, it will return different hashes. I'm guessing it is based on the memory address where it is stored somehow.

Get next N elements from enumerable

Context: C# 3.0, .Net 3.5
Suppose I have a method that generates random numbers (forever):
private static IEnumerable<int> RandomNumberGenerator() {
while (true) yield return GenerateRandomNumber(0, 100);
}
I need to group those numbers in groups of 10, so I would like something like:
foreach (IEnumerable<int> group in RandomNumberGenerator().Slice(10)) {
Assert.That(group.Count() == 10);
}
I have defined Slice method, but I feel there should be one already defined. Here is my Slice method, just for reference:
private static IEnumerable<T[]> Slice<T>(IEnumerable<T> enumerable, int size) {
var result = new List<T>(size);
foreach (var item in enumerable) {
result.Add(item);
if (result.Count == size) {
yield return result.ToArray();
result.Clear();
}
}
}
Question: is there an easier way to accomplish what I'm trying to do? Perhaps Linq?
Note: above example is a simplification, in my program I have an Iterator that scans given matrix in a non-linear fashion.
EDIT: Why Skip+Take is no good.
Effectively what I want is:
var group1 = RandomNumberGenerator().Skip(0).Take(10);
var group2 = RandomNumberGenerator().Skip(10).Take(10);
var group3 = RandomNumberGenerator().Skip(20).Take(10);
var group4 = RandomNumberGenerator().Skip(30).Take(10);
without the overhead of regenerating number (10+20+30+40) times. I need a solution that will generate exactly 40 numbers and break those in 4 groups by 10.
Are Skip and Take of any use to you?
Use a combination of the two in a loop to get what you want.
So,
list.Skip(10).Take(10);
Skips the first 10 records and then takes the next 10.
I have done something similar. But I would like it to be simpler:
//Remove "this" if you don't want it to be a extension method
public static IEnumerable<IList<T>> Chunks<T>(this IEnumerable<T> xs, int size)
{
var curr = new List<T>(size);
foreach (var x in xs)
{
curr.Add(x);
if (curr.Count == size)
{
yield return curr;
curr = new List<T>(size);
}
}
}
I think yours are flawed. You return the same array for all your chunks/slices so only the last chunk/slice you take would have the correct data.
Addition: Array version:
public static IEnumerable<T[]> Chunks<T>(this IEnumerable<T> xs, int size)
{
var curr = new T[size];
int i = 0;
foreach (var x in xs)
{
curr[i % size] = x;
if (++i % size == 0)
{
yield return curr;
curr = new T[size];
}
}
}
Addition: Linq version (not C# 2.0). As pointed out, it will not work on infinite sequences and will be a great deal slower than the alternatives:
public static IEnumerable<T[]> Chunks<T>(this IEnumerable<T> xs, int size)
{
return xs.Select((x, i) => new { x, i })
.GroupBy(xi => xi.i / size, xi => xi.x)
.Select(g => g.ToArray());
}
Using Skip and Take would be a very bad idea. Calling Skip on an indexed collection may be fine, but calling it on any arbitrary IEnumerable<T> is liable to result in enumeration over the number of elements skipped, which means that if you're calling it repeatedly you're enumerating over the sequence an order of magnitude more times than you need to be.
Complain of "premature optimization" all you want; but that is just ridiculous.
I think your Slice method is about as good as it gets. I was going to suggest a different approach that would provide deferred execution and obviate the intermediate array allocation, but that is a dangerous game to play (i.e., if you try something like ToList on such a resulting IEnumerable<T> implementation, without enumerating over the inner collections, you'll end up in an endless loop).
(I've removed what was originally here, as the OP's improvements since posting the question have since rendered my suggestions here redundant.)
Let's see if you even need the complexity of Slice. If your random number generates is stateless, I would assume each call to it would generate unique random numbers, so perhaps this would be sufficient:
var group1 = RandomNumberGenerator().Take(10);
var group2 = RandomNumberGenerator().Take(10);
var group3 = RandomNumberGenerator().Take(10);
var group4 = RandomNumberGenerator().Take(10);
Each call to Take returns a new group of 10 numbers.
Now, if your random number generator re-seeds itself with a specific value each time it's iterated, this won't work. You'll simply get the same 10 values for each group. So instead, you would use:
var generator = RandomNumberGenerator();
var group1 = generator.Take(10);
var group2 = generator.Take(10);
var group3 = generator.Take(10);
var group4 = generator.Take(10);
This maintains an instance of the generator so that you can continue retrieving values without re-seeding the generator.
You could use the Skip and Take methods with any Enumerable object.
For your edit :
How about a function that takes a slice number and a slice size as a parameter?
private static IEnumerable<T> Slice<T>(IEnumerable<T> enumerable, int sliceSize, int sliceNumber) {
return enumerable.Skip(sliceSize * sliceNumber).Take(sliceSize);
}
It seems like we'd prefer for an IEnumerable<T> to have a fixed position counter so that we can do
var group1 = items.Take(10);
var group2 = items.Take(10);
var group3 = items.Take(10);
var group4 = items.Take(10);
and get successive slices rather than getting the first 10 items each time. We can do that with a new implementation of IEnumerable<T> which keeps one instance of its Enumerator and returns it on every call of GetEnumerator:
public class StickyEnumerable<T> : IEnumerable<T>, IDisposable
{
private IEnumerator<T> innerEnumerator;
public StickyEnumerable( IEnumerable<T> items )
{
innerEnumerator = items.GetEnumerator();
}
public IEnumerator<T> GetEnumerator()
{
return innerEnumerator;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return innerEnumerator;
}
public void Dispose()
{
if (innerEnumerator != null)
{
innerEnumerator.Dispose();
}
}
}
Given that class, we could implement Slice with
public static IEnumerable<IEnumerable<T>> Slices<T>(this IEnumerable<T> items, int size)
{
using (StickyEnumerable<T> sticky = new StickyEnumerable<T>(items))
{
IEnumerable<T> slice;
do
{
slice = sticky.Take(size).ToList();
yield return slice;
} while (slice.Count() == size);
}
yield break;
}
That works in this case, but StickyEnumerable<T> is generally a dangerous class to have around if the consuming code isn't expecting it. For example,
using (var sticky = new StickyEnumerable<int>(Enumerable.Range(1, 10)))
{
var first = sticky.Take(2);
var second = sticky.Take(2);
foreach (int i in second)
{
Console.WriteLine(i);
}
foreach (int i in first)
{
Console.WriteLine(i);
}
}
prints
1
2
3
4
rather than
3
4
1
2
Take a look at Take(), TakeWhile() and Skip()
I think the use of Slice() would be a bit misleading. I think of that as a means to give me a chuck of an array into a new array and not causing side effects. In this scenario you would actually move the enumerable forward 10.
A possible better approach is to just use the Linq extension Take(). I don't think you would need to use Skip() with a generator.
Edit: Dang, I have been trying to test this behavior with the following code
Note: this is wasn't really correct, I leave it here so others don't fall into the same mistake.
var numbers = RandomNumberGenerator();
var slice = numbers.Take(10);
public static IEnumerable<int> RandomNumberGenerator()
{
yield return random.Next();
}
but the Count() for slice is alway 1. I also tried running it through a foreach loop since I know that the Linq extensions are generally lazily evaluated and it only looped once. I eventually did the code below instead of the Take() and it works:
public static IEnumerable<int> Slice(this IEnumerable<int> enumerable, int size)
{
var list = new List<int>();
foreach (var count in Enumerable.Range(0, size)) list.Add(enumerable.First());
return list;
}
If you notice I am adding the First() to the list each time, but since the enumerable that is being passed in is the generator from RandomNumberGenerator() the result is different every time.
So again with a generator using Skip() is not needed since the result will be different. Looping over an IEnumerable is not always side effect free.
Edit: I'll leave the last edit just so no one falls into the same mistake, but it worked fine for me just doing this:
var numbers = RandomNumberGenerator();
var slice1 = numbers.Take(10);
var slice2 = numbers.Take(10);
The two slices were different.
I had made some mistakes in my original answer but some of the points still stand. Skip() and Take() are not going to work the same with a generator as it would a list. Looping over an IEnumerable is not always side effect free. Anyway here is my take on getting a list of slices.
public static IEnumerable<int> RandomNumberGenerator()
{
while(true) yield return random.Next();
}
public static IEnumerable<IEnumerable<int>> Slice(this IEnumerable<int> enumerable, int size, int count)
{
var slices = new List<List<int>>();
foreach (var iteration in Enumerable.Range(0, count)){
var list = new List<int>();
list.AddRange(enumerable.Take(size));
slices.Add(list);
}
return slices;
}
I got this solution for the same problem:
int[] ints = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
IEnumerable<IEnumerable<int>> chunks = Chunk(ints, 2, t => t.Dump());
//won't enumerate, so won't do anything unless you force it:
chunks.ToList();
IEnumerable<T> Chunk<T, R>(IEnumerable<R> src, int n, Func<IEnumerable<R>, T> action){
IEnumerable<R> head;
IEnumerable<R> tail = src;
while (tail.Any())
{
head = tail.Take(n);
tail = tail.Skip(n);
yield return action(head);
}
}
if you just want the chunks returned, not do anything with them, use chunks = Chunk(ints, 2, t => t). What I would really like is to have to have t=>t as default action, but I haven't found out how to do that yet.

Access Enumerator within a foreach loop?

I have a List class, and I would like to override GetEnumerator() to return my own Enumerator class. This Enumerator class would have two additional properties that would be updated as the Enumerator is used.
For simplicity (this isn't the exact business case), let's say those properties were CurrentIndex and RunningTotal.
I could manage these properties within the foreach loop manually, but I would rather encapsulate this functionality for reuse, and the Enumerator seems to be the right spot.
The problem: foreach hides all the Enumerator business, so is there a way to, within a foreach statement, access the current Enumerator so I can retrieve my properties? Or would I have to foreach, use a nasty old while loop, and manipulate the Enumerator myself?
Strictly speaking, I would say that if you want to do exactly what you're saying, then yes, you would need to call GetEnumerator and control the enumerator yourself with a while loop.
Without knowing too much about your business requirement, you might be able to take advantage of an iterator function, such as something like this:
public static IEnumerable<decimal> IgnoreSmallValues(List<decimal> list)
{
decimal runningTotal = 0M;
foreach (decimal value in list)
{
// if the value is less than 1% of the running total, then ignore it
if (runningTotal == 0M || value >= 0.01M * runningTotal)
{
runningTotal += value;
yield return value;
}
}
}
Then you can do this:
List<decimal> payments = new List<decimal>() {
123.45M,
234.56M,
.01M,
345.67M,
1.23M,
456.78M
};
foreach (decimal largePayment in IgnoreSmallValues(payments))
{
// handle the large payments so that I can divert all the small payments to my own bank account. Mwahaha!
}
Updated:
Ok, so here's a follow-up with what I've termed my "fishing hook" solution. Now, let me add a disclaimer that I can't really think of a good reason to do something this way, but your situation may differ.
The idea is that you simply create a "fishing hook" object (reference type) that you pass to your iterator function. The iterator function manipulates your fishing hook object, and since you still have a reference to it in your code outside, you have visibility into what's going on:
public class FishingHook
{
public int Index { get; set; }
public decimal RunningTotal { get; set; }
public Func<decimal, bool> Criteria { get; set; }
}
public static IEnumerable<decimal> FishingHookIteration(IEnumerable<decimal> list, FishingHook hook)
{
hook.Index = 0;
hook.RunningTotal = 0;
foreach(decimal value in list)
{
// the hook object may define a Criteria delegate that
// determines whether to skip the current value
if (hook.Criteria == null || hook.Criteria(value))
{
hook.RunningTotal += value;
yield return value;
hook.Index++;
}
}
}
You would utilize it like this:
List<decimal> payments = new List<decimal>() {
123.45M,
.01M,
345.67M,
234.56M,
1.23M,
456.78M
};
FishingHook hook = new FishingHook();
decimal min = 0;
hook.Criteria = x => x > min; // exclude any values that are less than/equal to the defined minimum
foreach (decimal value in FishingHookIteration(payments, hook))
{
// update the minimum
if (value > min) min = value;
Console.WriteLine("Index: {0}, Value: {1}, Running Total: {2}", hook.Index, value, hook.RunningTotal);
}
// Resultint output is:
//Index: 0, Value: 123.45, Running Total: 123.45
//Index: 1, Value: 345.67, Running Total: 469.12
//Index: 2, Value: 456.78, Running Total: 925.90
// we've skipped the values .01, 234.56, and 1.23
Essentially, the FishingHook object gives you some control over how the iterator executes. The impression I got from the question was that you needed some way to access the inner workings of the iterator so that you could manipulate how it iterates while you are in the middle of iterating, but if this is not the case, then this solution might be overkill for what you need.
With foreach you indeed can't get the enumerator - you could, however, have the enumerator return (yield) a tuple that includes that data; in fact, you could probably use LINQ to do it for you...
(I couldn't cleanly get the index using LINQ - can get the total and current value via Aggregate, though; so here's the tuple approach)
using System.Collections;
using System.Collections.Generic;
using System;
class MyTuple
{
public int Value {get;private set;}
public int Index { get; private set; }
public int RunningTotal { get; private set; }
public MyTuple(int value, int index, int runningTotal)
{
Value = value; Index = index; RunningTotal = runningTotal;
}
static IEnumerable<MyTuple> SomeMethod(IEnumerable<int> data)
{
int index = 0, total = 0;
foreach (int value in data)
{
yield return new MyTuple(value, index++,
total = total + value);
}
}
static void Main()
{
int[] data = { 1, 2, 3 };
foreach (var tuple in SomeMethod(data))
{
Console.WriteLine("{0}: {1} ; {2}", tuple.Index,
tuple.Value, tuple.RunningTotal);
}
}
}
You can also do something like this in a more Functional way, depending on your requirements. What you are asking can be though of as "zipping" together multiple sequences, and then iterating through them all at once. The three sequences for the example you gave would be:
The "value" sequence
The "index" sequence
The "Running Total" Sequence
The next step would be to specify each of these sequences seperately:
List<decimal> ValueList
var Indexes = Enumerable.Range(0, ValueList.Count)
The last one is more fun... the two methods I can think of are to either have a temporary variable used to sum up the sequence, or to recalculate the sum for each item. The second is obviously much less performant, I would rather use the temporary:
decimal Sum = 0;
var RunningTotals = ValueList.Select(v => Sum = Sum + v);
The last step would be to zip these all together. .Net 4 will have the Zip operator built in, in which case it will look like this:
var ZippedSequence = ValueList.Zip(Indexes, (value, index) => new {value, index}).Zip(RunningTotals, (temp, total) => new {temp.value, temp.index, total});
This obviously gets noisier the more things you try to zip together.
In the last link, there is source for implementing the Zip function yourself. It really is a simple little bit of code.

Swap List<> elements with c# using LINQ

I have this list
var list = new List { 3, 1, 0, 5 };
I want to swap element 0 with 2
output
0, 1, 3, 5
If you just want it sorted, I'd use List.Sort().
If you want to swap, there is no built in method to do this. It'd be easy to write an extension method, though:
static void Swap<T>(this List<T> list, int index1, int index2)
{
T temp = list[index1];
list[index1] = list[index2];
list[index2] = temp;
}
You could then do:
list.Swap(0,2);
Classic swap is...
int temp = list[0];
list[0] = list[2];
list[2] = temp;
I don't think Linq has any 'swap' functionality if that's what you're looking for.
In the case that something is not directly supported ...make it so number 1!
Take a look at the concept of "extension methods". With this you can easily make your list support the concept of Swap() (this applies to any time you want to extend the functionality of a class).
namespace ExtensionMethods
{
//static class
public static class MyExtensions
{
//static method with the first parameter being the object you are extending
//the return type being the type you are extending
public static List<int> Swap(this List<int> list,
int firstIndex,
int secondIndex)
{
int temp = list[firstIndex];
list[firstIndex] = list[secondIndex];
list[secondIndex] = temp;
return list;
}
}
}

Categories

Resources