C# Set collection?
Try HashSet:
The HashSet(Of T) class provides high-performance set operations. A set is a collection that contains no duplicate elements, and whose elements are in no particular order...
The capacity of a HashSet(Of T) object is the number of elements that the object can hold. A HashSet(Of T) object's capacity automatically increases as elements are added to the object.
The HashSet(Of T) class is based on the model of mathematical sets and provides high-performance set operations similar to accessing the keys of the Dictionary(Of TKey, TValue) or Hashtable collections. In simple terms, the HashSet(Of T) class can be thought of as a Dictionary(Of TKey, TValue) collection without values.
A HashSet(Of T) collection is not sorted and cannot contain duplicate elements...
What is the C# equivalent of the stl set?
If you require sorted set, use
SortedDictionary<T,U>
. This is implemented using a binary search tree. Admittedly, you will be using 64-bits per entry because you are storing a key-value pair underneath. You can write a wrapper around it like this:class Set<T> : SortedDictionary<T, bool>
{
public void Add(T item)
{
this.Add(item, true);
}
}If you don't require a sorted set, use
HashSet<T>
.Otherwise, check out C5 Generic Collection Library. In particular
TreeSet<T>
. It is a red-black tree and only stores the values.
Set collection to modified Entity Framework
context.Entry
represents a single entity, never a collection. So you have to loop through the collection and mark each entity as modified.
Unique collection set
Expanding on the comments, if you want the row to function as an aggregate hash instead of just as a key, you would want to create a custom IEqualityComparer<(string, string)>
and pass it to a HashSet.
public class ValueTupleEqualityComparer : IEqualityComparer<(string s1, string s2)>
{
public bool Equals((string s1, string s2) other)
{
return base.Equals(other);
}
public bool Equals((string s1, string s2) x, (string s1, string s2) y)
{
if (object.ReferenceEquals(x, y))
return true;
if (x.s1 == y.s1 && x.s2 == y.s2)
return true;
if (x.s1 == y.s2 && x.s2 == y.s1)
return true;
return false;
}
public int GetHashCode((string s1, string s2) obj)
{
return base.GetHashCode();
}
}
When testing this against your data set:
var hashSet = new HashSet<(string s1, string s2)>(new ValueTupleEqualityComparer());
hashSet.Add(("txt", "data"));
hashSet.Add(("txt", "txt"));
hashSet.Add(("txt", "data"));
hashSet.Add(("data", "txt"));
hashSet.Add(("exe", "path"));
hashSet.Add(("exe", "path2"));
hashSet.Add(("exe", "path"));
the following results are outputted:
txt data
txt txt
exe path
exe path2
This gives you unique results where both the "column1" and "column2" are used, regardless of order.
Collection that allows only unique items in .NET?
HashSet<T>
is what you're looking for. From MSDN (emphasis added):
The
HashSet<T>
class provides high-performance set operations. A set is a collection that contains no duplicate elements, and whose elements are in no particular order.
Note that the HashSet<T>.Add(T item)
method returns a bool
-- true
if the item was added to the collection; false
if the item was already present.
Does a collection initialize set the initial size of a HashSet properly?
TL;DR; Don't use a collection initializer, if you have a pre-existing array or collection.
The collection initializer just uses Add()
to create the collection, so yes, it is slightly better for performance to set the size first. It's unlikely you will actually notice any difference in most cases though.
The code for the relevant HashSet constructor has this little gem:
public HashSet(IEnumerable<T> collection, IEqualityComparer<T> comparer)
{
...........
// to avoid excess resizes, first set size based on collection's count. Collection
// may contain duplicates, so call TrimExcess if resulting hashset is larger than
// threshold
ICollection<T> coll = collection as ICollection<T>;
int suggestedCapacity = coll == null ? 0 : coll.Count;
Initialize(suggestedCapacity);
this.UnionWith(collection);
So if you have an existing array (which is an ICollection<T>
, as is a List<T>
) then it won't matter. It's only an issue when using LINQ Where
etc, or when using collection initializers.
Modify collection items using reflection?
readonly
only applies to the field and means that you cannot assign it another (or the same) collection instance or null
. It does not mean that the collection itself is a read-only collection.
Since you have a variable myCollection
typed as List<string>
, you do not need Reflection. Just write
myCollection.Add("some value"); // allowed.
Note that a List<T>
is a class and therefore a reference type. I.e., the variable myCollection
contains a reference to the real collection. myCollection.Add("some value");
adds the new value to the real collection (MyAssembly.Constants.MyCollection
)!
But something like Constants.MyCollection = null;
is not allowed because of the readonly
keyword.
Example:
static readonly List<string> myCollection = new List<string>();
static ReadOnlyCollection<string> roc = new ReadOnlyCollection<string>(myCollection);
readonly
fields or properties can be initialized with an initializer expression or in a constructor. Given the declarations above:
myCollection.Add("text"); // OK, collection not readonly.
myCollection = new List<string>(); // NOT POSSIBLE, field readonly.
roc.Add("text"); // NOT POSSIBLE, readonly collection has no Add method.
roc = new ReadOnlyCollection<string>(new[] { "a", "b" }); // OK, roc field not readonly.
static
does not mean that the field or collection cannot be changed. It means that the field is not an instance field that must be referenced through a class instance (an object), rather, it belongs to the class and can be accessed through the class name.
Example:
class MyClass
{
public static int staticField;
public int instanceField;
}
Given the declaration above:
var obj = new MyClass();
var x = obj.instanceField; // OK
var y = MyClass.staticField; // OK
var z = MyClass.instanceField; // DOES NOT COMPILE!
// CS0120: An object reference is required for the nonstatic field, method, or property
// 'MyClass.instanceField'
var t = obj.staticField; // DOES NOT COMPILE!
// CS0176: Static member 'MyClass.staticField' cannot be accessed with an instance
// reference; qualify it with a type name instead
Related Topics
Servicestack.Net Redis: Storing Related Objects VS. Related Object Ids
How to Implement Real Time Data for a Web Page
Adding Parameters in SQLite with C#
Is Securestring Ever Practical in a C# Application
Display Image from Database in Asp MVC
C# Selenium 'Expectedconditions Is Obsolete'
Log4Net: Programmatically Specify Multiple Loggers (With Multiple File Appenders)
C# - Get a List of Files Excluding Those That Are Hidden
How to Implement a Never Ending Task. (Timers VS Task)
How to Install a Windows Service Programmatically in C#
An Attempt Was Made to Access a Socket in a Way Forbidden by Its Access Permissions. Why
JSON Convert Empty String Instead of Null
Returning Only Part of Match from Regular Expression
Collection<T> Versus List<T> What Should You Use on Your Interfaces
How to Format a Number into a String with Leading Zeros