I want to create an class that represents an integer set using a HashSet<int>. I want it to keep track of which values are included in the set using that internal container. I've done this so far:
class SetInteger
{
HashSet<int> intTest= new HashSet<int>();
intTest.Add(1);
intTest.Add(2);
intTest.Add(3);
intTest.Add(4);
intTest.Add(5);
intTest.Add(6);
intTest.Add(7);
intTest.Add(8);
intTest.Add(9);
intTest.Add(10);
}
So, here I think I'm adding some values to the HashSet, but I dont see how this can keep track of which values that are included in the set. Any ideas?
The hash set has a Contains method that allows you to check whether a value is in the set.
In addition, the HashSet<T> implements the ISet<T> interface and therefore provides many methods for working with sets, such as union, intersection and determining if a set of values is a (proper) super- or subset of your set.
HashSet<int> intTest = new HashSet<int>()
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
bool has4 = intTest.Contains(4); // Returns true
bool has11 = intTest.Contains(11); // Returns false
bool result = intTest.IsSupersetOf(new []{ 4, 6, 7 }); // Returns true
By the way, did you know about the collection initializer syntax?
You can also foreach on the set to get each element it contains (in an unspecified order):
foreach(int value in intTest)
{
// Do something with value.
}
Or convert it to an array or mutable list (also in an unspecified order):
int[] arr = intTest.ToArray();
List<int> lst = intTest.ToList();
Hmm...well, a HashSet<T> implements IEnumerable<T>, so you can always do this to figure out "What's already in there":
HashSet<int> intTest= new HashSet<int>();
intTest.Add(1);
intTest.Add(2);
intTest.Add(3);
intTest.Add(4);
intTest.Add(5);
intTest.Add(6);
intTest.Add(7);
intTest.Add(8);
intTest.Add(9);
intTest.Add(10);
var inThereNow = intTest.ToArray(); // [1,2,3,4,5,6,7,8,9,10]
There's also bool Contains(T value) which will tell you if a specific value is in the set, IEnumerable<T> Union(IEnumerable<T> other) which will tell you the "OR" of two sets, IEnumerable<T> Intersect(IEnumerable<T> other) which will tell you the overlap of two sets...pretty much anything in either IEnumerable<T> or ISet<T>
You can use HashSet Contains method tell's if the value already exists!
Example :
if (intTest.Contains(5))
{
// already has the value
}
Us the Contains method: http://msdn.microsoft.com/en-us/library/bb356440.aspx
Hope this helps.
you can try this. you just take a one textbox and two button.
HashSet<int> hs = new HashSet<int>();
private void savedataonhashSet_Click(object sender, EventArgs e)
{
hs.Add(Convert.ToInt16(textBox1.Text));
}
private void checkduplicatevalue_Click(object sender, EventArgs e)
{
if (hs.Contains(00))
{
MessageBox.Show("it is");
}
else
{
MessageBox.Show("not there");
}
}
if you again problem faced just drop your code .....
Related
Is it possible to use except with two lists of int arrays, like so:
List<int[]> a = new List<int[]>(){ new int[]{3,4,5}, new int[]{7,8,9}, new int[]{10,11,12} };
List<int[]> b = new List<int[]>(){ new int[]{6,7,9}, new int[]{3,4,5}, new int[]{10,41,12} };
var c = a.Except(b);
and exepecting {3,4,5} to be absent of the enumerable c? Of course I tried and this one is not working. Is there a solution as efficient as Except? Or even better, faster?
In .NET, arrays are only equal to another if they are the exact same array object. So two distinct arrays which have the same contents are not considered equal:
int[] x = new int[] { 1, 2 };
int[] y = new int[] { 1, 2 };
Console.WriteLine(x == y); // false
In order to check the equality based on the contents, you can use Enumerable.SequenceEqual:
Console.WriteLine(x.SequenceEqual(y)); // true
Of course that doesn’t help you directly when trying to use Enumerable.Except, since by default that will use the default equality comparer which only checks for equality (and since every array is inequal to every other array except itself…).
So the solution would be to use the other overload, and provide a custom IEqualityComparer which compares the arrays based on their content.
public class IntArrayEqualityComparer : IEqualityComparer<int[]>
{
public bool Equals(int[] a, int[] b)
{
return a.SequenceEqual(b);
}
public int GetHashCode(int[] a)
{
return a.Sum();
}
}
Unfortunately, just delegating to SequenceEqual is not enough. We also have to provide a GetHashCode implementation for this to work. As a simple solution, we can use the sum of the numbers in the array here. Usually, we would want to provide a strong hash function, which tells a lot about the contents, but since we are only using this hash function for the Except call, we can use something simple here. (In general, we would also want to avoid creating a hash value from a mutable object)
And when using that equality comparer, we correctly filter out the duplicate arrays:
var c = a.Except(b, new IntArrayEqualityComparer());
That's because default EqualityComparer for int array returns false for to arrays with same values:
int[] a1 = { 1, 2, 3 };
int[] a2 = { 1, 2, 3 };
var ec = EqualityComparer<int[]>.Default;
Console.WriteLine(ec.Equals(a1, a2));//result is false
You can fix it by implementing your own EqualityComparer and passing its instance to Except method (see documentation).
You can also read about arrays comparison in C# here.
What are the ways to check if X exists in X,Y,Z in c#?
For eg:
X=5;
I want to check if X's value matches any of the comma separated values..
if(x in (2,5,12,14)
new int[] { 2,5,12,14}.Contains(x);
List<int> list = new List<int> { 1, 2, 3, 4, 5 };
list.Contains(5);
You may use .Contains method. e.g. listItems.Contains(x)
There is no in operator in C#, but you can implement an extension method to make the code more readable.
public static class Ext
{
public static bool In<T>(this T val, params T[] values) where T : struct
{
return values.Contains(val);
}
}
//usage: var exists = num.In(numbers);
Linq.Contains() what you searching for
// Create List with three elements.
var list = new List<string>();
list.Add("cat");
list.Add("dog");
list.Add("moth");
// Search for this element.
if (list.Contains("dog"))
{
Console.WriteLine("dog was found");
}
There are two methods Linq.Contains() method and an extension Linq.Contains<int>
var list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// Use extension method.
var stp = new Stopwatch();
stp.Start();
bool a = list.Contains<int>(7);
stp.Stop();
Console.WriteLine("Time in extenstion method {0}", stp.Elapsed);
stp.Restart();
// Use instance method.
bool b = list.Contains(7);
stp.Stop();
Console.WriteLine("Time in normal method {0}", stp.Elapsed);
Performance benchmark : The version specific to List i.e, list.Contains(7); , found on the List type definition, is faster. I tested the same List with the two Contains methods.
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
I have the next C# code:
Dictionary<string, int> d = new Dictionary<string, int>();
d.Add("a", 3);
d.Add("b", 1);
d.Add("c", 0);
d.Add("d", -1);
d.Add("e", -9);
When searching the key "c" I want to get the position of this key, i.e. 2. If I look for the key "e", I want to get 4. If the element is not found the relative position could be -1.
Added:
Unless you have a better idea, I want to populate a matrix with certain values in a row number indicated by the relative position of a dictionary element found. The same applies for the column but using a different dictionary. An example:
n4 n2 n1 n3 n9 . . .
a 4/4
b 2 8
c
d 8/2
e 4/3
.
.
.
Where a,b,c,d,e,... are the keys of dictionay "d" and n4,n2,n3,n9 are the keys of a second dictionary.
How can I get this?
There's no such thing as a "position" within a Dictionary<,> - it's an unordered collection.
There are similar collections sorted by key - SortedList<,> and SortedDictionary<,>. Note that those are ordered by key rather than insertion time though. It's not clear which you want.
This should do the trick:
d.Keys.ToList().IndexOf("c");
Please Note that the O(1) time lookup offered by the Dictionary is lost when converting to the List, because Lists are inherently O(n). So if your Dictionary has a large number of elements, you're probably better off using another Dictionary or Matrix dimension to store the positions, since retrieving them in this manner will likely be slower. In fact, you should probably assume that the one-liner above is similar to:
GetDictKeyPos(d, "c");
public int GetDictKeyPos(Dictionary<string, int> d, string key)
{
for (int i = 0; i < d.Count; ++i)
{
if (d.ElementAt(i).Key == key)
return i;
}
return -1;
}
As a side note, if you are trying to get the position, you're probably making the assumption that the position is preserved. Microsoft says don't count on it, but in practice you'll discover that you probably can count on it. (I've never seen position not be preserved.) That being said, until Microsoft admits that, "Yeah, yeah, we've been holding out on you: position actually is preserved in a Dictionary. We just didn't want to admit it because we wanted to be able to change it if we found a better implementation, but now we know we're going to leave it, so here ya go...", you probably shouldn't assume that position is preserved.
Lastly, if you are planning to take your chances and assume it's preserved, and you also plan to use the above method to get the position, then consider storing the keys in a List instead, since the lookup time will be the same, and List order is guaranteed to be preserved.
Dictionaries have no implied order of key-value pairs. If you need the "position," you are using them the wrong way.
On your edit: If you are implementing a matrix, your best bet would be to use a multidimensional array. Eg:
int[,] matrix = new int[3, 2] { {1, 2}, {3, 4}, {5, 6} };
Is equivalent to a matrix like:
1 2
3 4
5 6
You can access its elements using matrix[i][j]; eg matrix[0][0] is 1, matrix[0][1] is 2, etc.
You will not be able to use any of the builtin collection data structures including KeyedCollection. However, you can easily make your own collection class by deriving from Collection and which contains a Dictionary internally for quick lookups on the key. The Collection class itself provides the ability for indexed retrieval.
public class KeyValueCollection<TKey, TValue> : Collection<KeyValuePair<TKey, TValue>>
{
private Dictionary<TKey, TValue> m_Dictionary = new Dictionary<TKey, TValue>();
public TValue GetValue(TKey key)
{
return m_Dictionary[key];
}
public void Add(TKey key, TValue value)
{
m_Dictionary.Add(key, value);
base.Add(new KeyValuePair<TKey, TValue>(key, value));
}
protected override void ClearItems()
{
m_Dictionary.Clear();
base.ClearItems();
}
protected override void InsertItem(int index, KeyValuePair<TKey, TValue> item)
{
m_Dictionary.Add(item.Key, item.Value);
base.InsertItem(index, item);
}
protected override void RemoveItem(int index)
{
m_Dictionary.Remove(this[index].Key);
base.RemoveItem(index);
}
protected override void SetItem(int index, KeyValuePair<TKey, TValue> item)
{
m_Dictionary[this[index].Key] = item.Value;
base.SetItem(index, item);
}
}
If you are really looking for that functionality, why don't you maintain an auxilary data structure which maintains the order in which you added the elements
(OR)
Probably you want to just maintain a List of Structures which store
[{"a",-1},{"b",1},{"c",0},{"d",-1},{"e",-9}]
So I'm trying to learn more about lambda expressions. I read this question on stackoverflow, concurred with the chosen answer, and have attempted to implement the algorithm using a console app in C# using a simple LINQ expression.
My question is: how do I translate the "var result" of the lambda expression into a usable object that I can then print the result?
I would also appreciate an in-depth explanation of what is happening when I declare the outer => outer.Value.Frequency
(I've read numerous explanations of lambda expressions but additional clarification would help)
C#
//Input : {5, 13, 6, 5, 13, 7, 8, 6, 5}
//Output : {5, 5, 5, 13, 13, 6, 6, 7, 8}
//The question is to arrange the numbers in the array in decreasing order of their frequency, preserving the order of their occurrence.
//If there is a tie, like in this example between 13 and 6, then the number occurring first in the input array would come first in the output array.
List<int> input = new List<int>();
input.Add(5);
input.Add(13);
input.Add(6);
input.Add(5);
input.Add(13);
input.Add(7);
input.Add(8);
input.Add(6);
input.Add(5);
Dictionary<int, FrequencyAndValue> dictionary = new Dictionary<int, FrequencyAndValue>();
foreach (int number in input)
{
if (!dictionary.ContainsKey(number))
{
dictionary.Add(number, new FrequencyAndValue(1, number) );
}
else
{
dictionary[number].Frequency++;
}
}
var result = dictionary.OrderByDescending(outer => outer.Value.Frequency);
// How to translate the result into something I can print??
For the answer complete with print commands, see my answer here.
how do I translate the "var result" of the lambda expression into a usable object that I can then print the result?
First off, the "lambda expression" is only the portion of the expression that is of the form a=>b. The rest of your query is just a method call that takes a lambda as its argument.
Anyway, if I could teach people one thing about LINQ it would be this: "result" isn't the results of the query, it is the query itself.
If you want to see the results, ask the query for each result:
foreach(var item in result)
Console.WriteLine(item.ToString());
I would also appreciate an in-depth explanation of what is happening when I declare the outer => outer.Value.Frequency
Sure. We begin by working out the types of everything involved. We see that the lambda is a function which takes a KeyValuePair and returns an int, so we generate a method
static private int MyLambda(KeyValuePair<int, FrequencyAndValue> outer)
{
return outer.Value.Frequency;
}
Next we take that method and create a delegate out of it:
var result = dictionary.OrderByDescending(
new Func<KeyValuePair<int, FrequencyAndValue>, int>(MyLambda));
and rewrite the extension method call:
var result = Enumerable.OrderByDescending<KeyValuePair<int, FrequencyAndValue>, int>(
dictionary,
new Func<KeyValuePair<int, FrequencyAndValue>, int>(MyLambda));
and rewrite the var:
IOrderedEnumerable<KeyValuePair<int, FrequencyAndValue>> result =
Enumerable.OrderByDescending<KeyValuePair<int, FrequencyAndValue>, int>(
dictionary,
new Func<KeyValuePair<int, FrequencyAndValue>, int>(MyLambda));
I hope you agree that the code you typed in is a whole lot more readable than this mess. Type inference rocks.
The result is an object which represents the ability to sort this dictionary by the given key. Read that carefully: it represents the ability to sort the dictionary by that key. It does not actually do that until you ask for a result; so far, all it is is an object that says "when asked for a result, sort the dictionary by this key".
Suppose you ask for a result. How does it compute the sorted list? It asks the dictionary for each element. Then it calls MyLambda on each element, which gives back an integer, so we now have a pair of dictionary key-value pairs and integers. It then builds a list of pairs sorted on that integer. Then it hands out elements of that list one at a time, as you ask for them.
We see that the lambda is a function which takes a KeyValuePair and returns an int" - How did you determine that? I don't see it from the method return value, nor documented in the OrderByDescending().
Ah, I see the confusion; for pedagogic reasons I fibbed a bit above regarding the exact order in which the semantic analysis proceeds.
How we do this type inference is one of the more subtle and interesting parts of C#.
Here's how it works.
We see that OrderByDescending is declared as:
static IOrderedEnumerable<T> OrderByDescending<T, K>(
this IEnumerable<T> sequence,
Func<T, K> keyExtractor)
and we see we have a potential call to this method:
OrderByDescending(dictionary, o=>o.Value.Frequency)
But we do not know what T and K are. So we start by looking at everything that is NOT a lambda. Your dictionary implements IEnumerable<KeyValuePair<int, FrequencyOrValue>> so we start by saying "T is probably KeyValuePair<int, FrequencyOrValue>".
At this point there is nothing else we can deduce from stuff that is not lambdas so we start looking at the lambdas. We see that we have a lambda o=>o.Value.Frequency and so far we have determined that the type of keyExtractor is Func<KeyValuePair<int, FrequencyOrValue>, K> and we are still looking for K. So we say suppose the lambda actually was:
(KeyValuePair<int, FrequencyOrValue> o)=>{return o.Value.Frequency;}
And we ask does it bind? YES! Yes it does. We can successfully compile this lambda without error and when we do so, we see that all of its return statements return an int.
Therefore we deduce that K is int, and we now have a full type analysis of the whole thing.
This is a fairly straightforward inference; they can get much weirder. See the "type inference" archive on my blog if this subject particularly interests you.
http://blogs.msdn.com/ericlippert/archive/tags/Type+Inference/default.aspx
In particular, here's a video of me explaining the stuff above plus a few other interesting cases:
http://blogs.msdn.com/ericlippert/archive/2006/11/17/a-face-made-for-email-part-three.aspx
The OrderByDescending Function will return a IEnumerable, actually a IOrderedEnumerable where the TSource is the type source of the original enumerable.
As you are working with a Dictionary, the OrderByDescending will return a:
IOrderedEnumerable<KeyValuePair<int, FrequencyAndValue>>
object, which will be ordered according to the expression provided.
var result = dictionary.OrderByDescending(outer => outer.Value.Frequency);
This line is giving you an IOrderedEnumerable<KeyValuePair<int, FrequencyAndValue>> called result. As for the lambda, it is of the type
Func<KeyValuePair<int,FrequencyAndValue>, int>
Which means it accepts a KeyValuePair<int, FrequencyAndValue> parameter (which you are calling outer), and returns an integer corresponding to the pair's value's Frequency property. So the resulting IOrderedEnumerable is being sorted by the frequency in a reverse order.
For the sake of full answer documentation, I printed the output using the more general "item" as well as the more specific IOrderedEnumerable.
C#
static void Main(string[] args)
{
//Input : {5, 13, 6, 5, 13, 7, 8, 6, 5}
//Output : {5, 5, 5, 13, 13, 6, 6, 7, 8}
//The question is to arrange the numbers in the array in decreasing order of their frequency, preserving the order of their occurrence.
//If there is a tie, like in this example between 13 and 6, then the number occurring first in the input array would come first in the output array.
List<int> input = new List<int>();
input.Add(5);
input.Add(13);
input.Add(6);
input.Add(5);
input.Add(13);
input.Add(7);
input.Add(8);
input.Add(6);
input.Add(5);
Dictionary<int, FrequencyAndValue> dictionary = new Dictionary<int, FrequencyAndValue>();
foreach (int number in input)
{
if (!dictionary.ContainsKey(number))
{
dictionary.Add(number, new FrequencyAndValue(1, number) );
}
else
{
dictionary[number].Frequency++;
}
}
var result = dictionary.OrderByDescending(outer => outer.Value.Frequency);
// BEGIN Priting results with the help of stackoverflow answers
Console.Write("With Items: ");
foreach (var item in result)
{
for (int i = 0; i < item.Value.Frequency; i++)
{
Console.Write(item.Value.Value + " ");
}
//Console.WriteLine(item.Value.Frequency + " " + item.Value.Value);
}
Console.WriteLine();
Console.Write("With IOrderedEnumerable: ");
IOrderedEnumerable<KeyValuePair<int, FrequencyAndValue>> myres = result;
foreach (KeyValuePair<int, FrequencyAndValue> fv in myres)
{
for(int i = 0; i < fv.Value.Frequency; i++ )
{
Console.Write(fv.Value.Value + " ");
}
}
Console.WriteLine();
// END Priting results with the help of stackoverflow answers
Console.ReadLine();
}
class FrequencyAndValue
{
public int Frequency{ get; set;}
public int Value{ get; set;}
public FrequencyAndValue(int myFreq, int myValue)
{
Value = myValue;
Frequency = myFreq;
}
}
}