Custom extension methods on IEnumerable<T> - c#

In my project we are getting different list and array of elements and need to pick alternative for those list and array for example if my list consist of
string[] toys= { "car", "bat-mask", "halloween-toys", "marvel-toys", "transformer" };
now it may be a list of hundreds of elements my problems is to choose alternative from above list like if i have configuratioin to pick one after another i.e car after that skip bat-mask and pick halloween-toys this is my first priority and after that i make it configurable like how many item to skip in between like one item or two items etc.
Reason to use it as extension because it will be use inside complete app and i simply need it access like var myList = toys.customExtensionMethods();

You can use that:
using System.Linq;
static public class IEnumerableHelper
{
static public IEnumerable<T> customExtensionMethods<T>(this IEnumerable<T> items,
T takeFirst,
int skipCount)
{
var list1 = items.SkipWhile(item => !item.Equals(takeFirst));
var list2 = list1.Skip(skipCount + 1).Take(1);
return list1.Take(1).Concat(list2);
}
}
Test 1
static void Test()
{
string[] toys = { "car", "bat-mask", "halloween-toys", "marvel-toys", "transformer" };
var list = toys.customExtensionMethods("car", 1);
foreach ( var item in list )
Console.WriteLine(item);
}
Output:
car
halloween-toys
Test 2
var list = toys.customExtensionMethods("bat-mask", 2);
Output
bat-mask
transformer

If i am not wrong, inside your extension method you want to get array element with no Of skip value passed.
public static class ExtensionMethod
{
public static string[] CustomExtensionMethods(this string[] myData, int NoofSkip)
{
var newData = new List<string>();
for (int i = 0; i < myData.Length; i++ )
{
newData.Add(myData[i]);
i = i + NoofSkip;
}
return newData.ToArray();
}
}
Call Method:
var data = toys.CustomExtensionMethods(1);
OutPut:
{ "car", "halloween-toys", "transformer" };

I hope I understood your question correctly. You are intending to create an extension method which takes an input 'searchterm' and a count skip count. The method searches for the item in the list, skips the next n items and returns the new item. You could do as the following.
public static class Extensions
{
public static T PickAlternative<T>(this IEnumerable<T> source,string item,int skipCount)
{
return source.SkipWhile(x=> !x.Equals(item)).Skip(skipCount).First();
}
}
Example,
toys.PickAlternative("bat-mask",3);
toys.PickAlternative("car",2);
Output
transformer
halloween-toys

public static class EnumerableExtensions
{
public static IEnumerable<T> PickAlternate<T>(this IEnumerable<T> source, int skip)
{
int? currentlySkipped = null;
foreach (var item in source)
{
if (!currentlySkipped.HasValue || currentlySkipped == skip)
{
currentlySkipped = 0;
yield return item;
}
else
{
currentlySkipped++;
}
}
}
}

Related

Implement class to work with real time data

Using C# I need to transform a time series, for example:
Input: 1 2 1 0 3 2 -> Output: 1 3 4 4 7 9
In the previous example an output is the sum of current input with the previous inputs.
I will have different transformations so I started with an abstract class:
public abstract class Transformation<TInput, TOutput> {
private IEnumerable<TInput> _inputs { get; set; }
public Transformation(IEnumerable<TInput> inputs) {
_inputs = inputs;
}
public abstract IEnumerable<TOutput> Calculate();
}
So a transformation would be something like:
public class TransformationOne<Int32, Int32> {
public override IEnumerable<Int32> Calculate();
// Calculate the outputs with all inputs
}
}
This works fine if I have all inputs and want all outputs.
But sometimes I would like to use my class in real time.
So I would feed with a new input and would get a new output.
What would be the best way to implement this?
Keep the state in the class and send the input to the Calculate method?
class TransformationOne
{
private int _currentResult;
public int Calculate(int value)
{
_currentResult += value;
return _currentResult;
}
}
so you could do:
var transformationOne = new TransformationOne();
var inputs = new List<int> {1, 2, 1, 0, 3, 2};
foreach (var input in inputs)
{
var newResult = transformationOne.Calculate(input);
Console.WriteLine(newResult); // results: 1 3 4 4 7 9
}
Demo
My answer is very similar to what #Julian did. However, I had already written my solution, I think it does a better job of providing the two aspects of the OP's question:
How to do this for a sequence of data (like what was originally shown)
How do use the same capability for one-at-a-time data
You can't easily do this with a generic, there is no way to constrain a type to one that includes addition (if you know of one, let me now). So this is what the transformation class looks like:
public class AccumulateTransformer
{
private int currentState = 0;
public void Clear()
{
currentState = default(int);
}
public int NextValue(int input)
{
currentState += input;
return currentState;
}
public int Current => currentState;
public IEnumerable<int> TransformSequence(IEnumerable<int> inputs, bool clearFirst = true)
{
if (clearFirst)
{
Clear();
}
foreach (var value in inputs)
{
yield return NextValue(value);
}
}
}
And here's some code to test it (using your data):
var transformer = new AccumulateTransformer();
var inputs = new[] {1, 2, 1, 0, 3, 2,};
var results = transformer.TransformSequence(inputs);
Debug.WriteLine(string.Join(", ", from result in results select result.ToString() ));
transformer.Clear();
Debug.WriteLine(transformer.NextValue(1));
Debug.WriteLine(transformer.NextValue(2));
Debug.WriteLine(transformer.NextValue(1));
Debug.WriteLine(transformer.NextValue(0));
Debug.WriteLine(transformer.NextValue(3));
Debug.WriteLine(transformer.NextValue(2));
The output of that looks like:
1, 3, 4, 4, 7, 9
1
3
4
4
7
9
To make this generic, you need a way of doing the accumulation operation that isn't dependent on T understanding addition. To do that, change the code to what's show below.
It makes the type generic on T (which would be int in this case), but includes a constructor that takes a Func<T, T, T> that will do the accumulation. When you construct your instance, you provide a Func that just adds two numbers.
The class code:
public class AccumulateTransformer<T>
{
private T _currentState = default(T);
private Func<T, T, T> _accumulator;
public AccumulateTransformer(Func<T, T, T> accumulator)
{
_accumulator = accumulator;
}
public void Clear()
{
_currentState = default(T);
}
public T NextValue(T input)
{
_currentState = _accumulator(_currentState, input);
return _currentState;
}
public T Current => _currentState;
public IEnumerable<T> TransformSequence(IEnumerable<T> inputs, bool clearFirst = true)
{
if (clearFirst)
{
Clear();
}
foreach (var value in inputs)
{
yield return NextValue(value);
}
}
The only difference in using this is that you have to provide that accumulate Func in the constructor:
var transformer = new AccumulateTransformer<int>((a, b) => a + b);
Otherwise, it's used the same way and produces the same output.
I'm not sure if this is exactly what you're after, but you could simply keep a list of the items in the class, and provide public methods for adding new items to it:
public class Transformer
{
private readonly List<int> items = new List<int>();
public IEnumerable<int> Items => items.ToList();
public void Add(int item) => items.Add(items.LastOrDefault() + item);
public void Add(IEnumerable<int> input)
{
foreach (var item in input) Add(item);
}
public override string ToString()
{
return string.Join(", ", Items);
}
}
In use it might look like:
public static void Main(string[] args)
{
var trans = new Transformer();
var items = new[] { 1, 2, 1, 0, 3 };
// Add a bunch of inputs at once:
trans.Add(items);
// Display results
Console.WriteLine($"After adding 5 items: {trans}");
// Add a single item
trans.Add(2);
// Display results
Console.WriteLine($"After adding 1 more item: {trans}");
GetKeyFromUser("\nDone! Press any key to exit...");
}
Output
A simple Linq.Select() would do that:
int sum = 0;
var result = input.Select(x => { sum += x; return sum; });
Live Demo

Actual difference between two lists - not Except

Let's say I have the list
var L1 = new List<int>{1,1,2};
var L2 = new List<int>{1};
If I do
L1.Except(L2)
I get List<int>{2} - Fair enough.
But is there shorthand to do something like L1.Minus(L2) where I would get List<int>{1,2}
Basically only remove items as many times as it finds them in L2.
I could write this out - hoping I don't have to.
If you were to write it yourself, it could look like this:
public static class ExtensionMethods
{
static public IEnumerable<T> Minus<T>(this IEnumerable<T> input, IEnumerable<T> removal)
{
var result = input.ToList();
foreach (var r in removal) result.Remove(r);
return result;
}
}
Or possibly like this if you aren't so worried about readability:
public static class ExtensionMethods
{
static public IEnumerable<T> Minus<T>(this IEnumerable<T> input, IEnumerable<T> removal)
{
var remaining = removal.ToList();
return input.Where
(
a => !remaining.Remove(a)
);
}
}
Example usage:
public class Program
{
public static void Main()
{
var L1 = new List<int>{1,1,2};
var L2 = new List<int>{1};
var L3 = L1.Minus(L2);
foreach (var l in L3)
{
Console.WriteLine(l);
}
}
}
Output:
1
2
Working example on DotNetFiddle
Minimal example using ForEach and a lambda expression:
L2.ForEach(x => L1.Remove(x));

C# limit List size, check total byte size and check for file name extension [duplicate]

When I want to make a value type read-only outside of my class I do this:
public class myClassInt
{
private int m_i;
public int i {
get { return m_i; }
}
public myClassInt(int i)
{
m_i = i;
}
}
What can I do to make a List<T> type readonly (so they can't add/remove elements to/from it) outside of my class? Now I just declare it public:
public class myClassList
{
public List<int> li;
public myClassList()
{
li = new List<int>();
li.Add(1);
li.Add(2);
li.Add(3);
}
}
You can expose it AsReadOnly. That is, return a read-only IList<T> wrapper. For example ...
public ReadOnlyCollection<int> List
{
get { return _lst.AsReadOnly(); }
}
Just returning an IEnumerable<T> is not sufficient. For example ...
void Main()
{
var el = new ExposeList();
var lst = el.ListEnumerator;
var oops = (IList<int>)lst;
oops.Add( 4 ); // mutates list
var rol = el.ReadOnly;
var oops2 = (IList<int>)rol;
oops2.Add( 5 ); // raises exception
}
class ExposeList
{
private List<int> _lst = new List<int>() { 1, 2, 3 };
public IEnumerable<int> ListEnumerator
{
get { return _lst; }
}
public ReadOnlyCollection<int> ReadOnly
{
get { return _lst.AsReadOnly(); }
}
}
Steve's answer also has a clever way to avoid the cast.
There is limited value in attempting to hide information to such an extent. The type of the property should tell users what they're allowed to do with it. If a user decides they want to abuse your API, they will find a way. Blocking them from casting doesn't stop them:
public static class Circumventions
{
public static IList<T> AsWritable<T>(this IEnumerable<T> source)
{
return source.GetType()
.GetFields(BindingFlags.Public |
BindingFlags.NonPublic |
BindingFlags.Instance)
.Select(f => f.GetValue(source))
.OfType<IList<T>>()
.First();
}
}
With that one method, we can circumvent the three answers given on this question so far:
List<int> a = new List<int> {1, 2, 3, 4, 5};
IList<int> b = a.AsReadOnly(); // block modification...
IList<int> c = b.AsWritable(); // ... but unblock it again
c.Add(6);
Debug.Assert(a.Count == 6); // we've modified the original
IEnumerable<int> d = a.Select(x => x); // okay, try this...
IList<int> e = d.AsWritable(); // no, can still get round it
e.Add(7);
Debug.Assert(a.Count == 7); // modified original again
Also:
public static class AlexeyR
{
public static IEnumerable<T> AsReallyReadOnly<T>(this IEnumerable<T> source)
{
foreach (T t in source) yield return t;
}
}
IEnumerable<int> f = a.AsReallyReadOnly(); // really?
IList<int> g = f.AsWritable(); // apparently not!
g.Add(8);
Debug.Assert(a.Count == 8); // modified original again
To reiterate... this kind of "arms race" can go on for as long as you like!
The only way to stop this is to completely break the link with the source list, which means you have to make a complete copy of the original list. This is what the BCL does when it returns arrays. The downside of this is that you are imposing a potentially large cost on 99.9% of your users every time they want readonly access to some data, because you are worried about the hackery of 00.1% of users.
Or you could just refuse to support uses of your API that circumvent the static type system.
If you want a property to return a read-only list with random access, return something that implements:
public interface IReadOnlyList<T> : IEnumerable<T>
{
int Count { get; }
T this[int index] { get; }
}
If (as is much more common) it only needs to be enumerable sequentially, just return IEnumerable:
public class MyClassList
{
private List<int> li = new List<int> { 1, 2, 3 };
public IEnumerable<int> MyList
{
get { return li; }
}
}
UPDATE Since I wrote this answer, C# 4.0 came out, so the above IReadOnlyList interface can take advantage of covariance:
public interface IReadOnlyList<out T>
And now .NET 4.5 has arrived and it has... guess what...
IReadOnlyList interface
So if you want to create a self-documenting API with a property that holds a read-only list, the answer is in the framework.
JP's answer regarding returning IEnumerable<int> is correct (you can down-cast to a list), but here is a technique that prevents the down-cast.
class ExposeList
{
private List<int> _lst = new List<int>() { 1, 2, 3 };
public IEnumerable<int> ListEnumerator
{
get { return _lst.Select(x => x); } // Identity transformation.
}
public ReadOnlyCollection<int> ReadOnly
{
get { return _lst.AsReadOnly(); }
}
}
The identity transformation during enumeration effectively creates a compiler-generated iterator - a new type which is not related to _lst in any way.
Eric Lippert has a series of articles on Immutability In C# on his blog.
The first article in the series can be found here.
You might also find useful Jon Skeet's answer to a similar question.
public List<int> li;
Don't declare public fields, it's generally considered bad practice... wrap it in a property instead.
You can expose your collection as a ReadOnlyCollection :
private List<int> li;
public ReadOnlyCollection<int> List
{
get { return li.AsReadOnly(); }
}
public class MyClassList
{
private List<int> _lst = new List<int>() { 1, 2, 3 };
public IEnumerable<int> ListEnumerator
{
get { return _lst.AsReadOnly(); }
}
}
To check it
MyClassList myClassList = new MyClassList();
var lst= (IList<int>)myClassList.ListEnumerator ;
lst.Add(4); //At this point ypu will get exception Collection is read-only.
public static IEnumerable<T> AsReallyReadOnly<T>(this IEnumerable<T> source)
{
foreach (T t in source) yield return t;
}
if I add to Earwicker's example
...
IEnumerable<int> f = a.AsReallyReadOnly();
IList<int> g = f.AsWritable(); // finally can't get around it
g.Add(8);
Debug.Assert(a.Count == 78);
I get InvalidOperationException: Sequence contains no matching element.

Retrieve values from next and previous elements in Sorted List C#

I have a sorted list that will pass in two elements and compare the two. Is there a function in the SortedList class in C# that will do a next and previous? I got some help with a .Skip, but since the keys would be variable, how would that work? All I need to do is take in the first element and second element, then skip to the third and fourth, fifth and sixth, etc. I wish it were as simple as LinkedList's ".next.next."
double velocity = positionList.Values.Skip(1);
Edit: The positionList is type
<double, HandCoordinate>
HandCoordinate = {double, double, double}
Does that help?
Thanks!
The class SortedList inherites IEnumerator, so you can use it:
SortedList list = ...
var listEnumerator = ((IEnumerable)list).GetEnumerator();
Pair<MyType> pair = null
do
{
pair = Pair.Next<MyType>(listEnumerator);
...
}
while(pair != null)
...
class Pair<T>
{
public T First {get; set;}
public T Second {get; set;}
public static Pair<T> Next<T>(IEnumerator enumerator)
{
var first = enumerator.Current;
if(enumerator.MoveNext())
{
return new Pair<T>
{
First = (T)first,
Second = (T)enumerator.Current,
}
}
return null;
}
}
List<int> ints = new List<int>();
ints.Add(1);
ints.Add(2);
ints.Add(3);
ints.Add(4);
for (int i = 0; i < ints.Count; i += 2)
{
var pair = ints.Skip(i).Take(2);
var first = pair.First();
var last = pair.Last();
}
Note: This should work, irrelevant of the type in theory. Unless the type is a drastically different format.
Without Skip().
var pair = new { First = ints[i], Second = ints[i += 1] };
The question is somewhat unclear. I'm assuming you need to get pairs of things from a list?
It's fairly easy to write an extension method that will present a sequence of pairs of items from an IEnumerable:
using System;
using System.Collections.Generic;
namespace Demo
{
internal static class Program
{
public static void Main()
{
double[] test = new double[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
foreach (var pair in test.AsPairs()) // This is how you use it.
{
Console.WriteLine("({0}, {1})", pair.Item1, pair.Item2);
// Or simply: Console.WriteLine(pair);
}
}
}
public static class EnumerableExt
{
public static IEnumerable<Tuple<T, T>> AsPairs<T>(this IEnumerable<T> sequence)
{
bool isFirst = true;
T first = default(T);
foreach (var item in sequence)
{
if (isFirst)
{
first = item;
isFirst = false;
}
else
{
isFirst = true;
yield return new Tuple<T, T>(first, item);
}
}
}
}
}

How to select distinct List<T>'s from a List<List<T>>?

HI, I am working on a simple class to combine items of any type... this is for a poker game, this is how it looks:
public static List<List<T>> combinar<T>(List<T> items, int take)
{
List<List<T>> combs = new List<List<T>>();
var stuff = permutar<T>(items, take);
var all = from s in stuff
select new Tuple<List<T>, string>(s, String.Join("", s.OrderBy(c => c).Select(c => c.ToString())));
var strs = all.Select(s => s.Item2).Distinct();
foreach (var str in strs)
{
combs.Add(all.First(a => a.Item2 == str).Item1);
}
return combs;
}
public static List<List<T>> permutar<T>(List<T> list, int take)
{
List<List<T>> combs = new List<List<T>>();
foreach (var item in list)
{
var newlist = list.Where(i => !i.Equals(item)).ToList();
var returnlist = take <= 1 ? new List<List<T>> { new List<T>() } : permutar(newlist, take - 1);
foreach (var l in returnlist)
{
l.Add(item);
}
combs.AddRange(returnlist);
}
return combs;
}
so permutation works perfect.. but I am having some trouble with combination, when T is Card it takes hell lots of time to complete... so my question is how to select distinct lists form the result of permutation???
this is the Card Class:
public class Card : IComparable
{
Suite _Suite;
public Suite Suite
{
get { return _Suite; }
set { _Suite = value; }
}
Grade _Grade;
public Grade Grade
{
get { return _Grade; }
set { _Grade = value; }
}
string _symbol;
public string Symbol
{
//stuff
}
public PictureBox Picture
{
//stuff
}
public override string ToString()
{
return _Grade.ToString() + " " + _Suite.ToString();
}
public int CompareTo(object obj)
{
Card card = (Card)obj;
return card.Grade > this.Grade ? -1 : card.Grade < this.Grade ? 1 : 0;
}
}
Assuming you don't want to make any big algorithmic changes, your biggest problem here is
combs.Add(all.First().Item1);
That doesn't make any sense. Perhaps you meant
combs.Add(all.First(c => c.Item2 == str)).Item1);
However, that would be very slow; if that's what you want, you should put the results of all into a hash table keyed by the string, and use that instead of looping through Distinct results.
If you wanted to get combinations without computing permutations first, the way to do it would be like this. Given some objects, to find the combinations of length K: if K is 0, return the empty list. Else, for each object, take that object, and then recursively append all the K-minus-1-length combinations of the rest of the objects.

Categories