Dictionary with multiple values for each key? [duplicate] - c#

This question already has answers here:
C# dictionary - one key, many values
(15 answers)
Closed 8 years ago.
I want the functionality of a Dictionary, but I want to store multiple values for each key. How can this be done in .NET/C#? Is there any built in collection that supports this scenario?
If I do the following:
collection.Add("key1", new Order(1));
collection.Add("key1", new Order(2));
collection.Add("key1", new Order(3));
collection.Add("key2", new Order(4));
Then running the following should return 3 orders.
collection["key1"];

Simple: Use Dictionary<string,List<Order>>

You may use lists for this purpose, if the number of orders per key needs to be variable.
collection.Add("key1"), new List<order>(){new Order(1), new Order(2)});

I would recommend using a List, Set, or Dictionary as appropriate for your Value in your Dictionary.
For example, you might do:
Dictionary<string, List<string>>

You should think about this in a different way. The Dictionary can hold a list of Orders rather than just a single one, like so:
var collection = Dictionary<string,List<Order>>();
collection.Add("key1", new List<Order>(new { new Order(1), new Order(2), new Order(3) });
collection.Add("key2", new Order(4));

Try this
Dictionary<string,order[] order> dict = new Dictionary<string,order[] order>();
how to access :
order[] orderArray = dict["key1"];
order order1 = orderArray[1] ;
order order2 = orderArray[2] ;
and goes on...

Related

C# copy List<dynamic> without reference [duplicate]

This question already has answers here:
In C# if an object in a list is added to another list, does changing the object in the second list change the same object in the first list?
(2 answers)
How to make correct clone of the List<MyObject>? [duplicate]
(3 answers)
Closed 5 years ago.
I have a List<dynamic> that I need to copy and then, based on a condition of the row of the list I need to modify a field of that row and add it to the second list.
This a sample of the code:
//list1 is a `List<dynamic>` that I get from a query using Dapper. I guess it is an ExpandoObject list
var list2 = new List<dynamic>(list1);
foreach (var obj in list2)
{
if (obj.condition == 1)
{
var newObj = obj;
newObj.description = "new row";
list2.Add(newObj);
}
}
My problem is that in both my list the obj in the list is updated with the string 'new row'.
It seems like every time I change newObj both lists are updated.
I also tried to create my list2 this way but I have the same problem:
var list2 = new BindingList<dynamic>(list1);
EDIT:
I looked at the other questions but in my case, I only have a dynamic List. Is it possible to get the result I want without having to create a Class and implement ICloneable?
Try
var list2 = list1.Select(x => x);

c# Dictionary<string,string> how to loop through items without knowing key [duplicate]

This question already has answers here:
How to iterate over a dictionary?
(29 answers)
Closed 8 years ago.
I have a:
var selectedDates = new Dictionary<string, string>();
selectedDates.Add("2014-06-21", DateTime.Now.ToLongDateString());
selectedDates.Add("2014-07-21", DateTime.Now.AddDays(5).ToLongDateString());
selectedDates.Add("2014-08-21", DateTime.Now.AddDays(9).ToLongDateString());
selectedDates.Add("2014-09-21", DateTime.Now.AddDays(14).ToLongDateString());
How can I loop trough items without knowing the key?
For example I want to get the value of the item[0]
If I do:
var item = selectedDates[0].value; // I get an error
How can I loop trough items without knowing the key?
For example I want to get the value of the item[0]
You want to treat the dictionary as (ordered) collection similar to a list or array and get the first item in it?
You can because a Dictionary<string, string> is an IEnumerable<KeyValuePair<string, string>> implicitly. Just use First or FirstOrDefault:
string valueAtFirstPosition = selectedDates.First().Value;
However, note that a dictionary is not meant to be used as as an ordered collection. It is a collection which can be used to fast-lookup a value by a key. But you can enumerate it anyway.
foreach(KeyValuePair<string, string>keyVal in selectedDates)
{
Console.WriteLine("Key: {0} Value: {1}", keyVal.Key, keyVal.Value);
}
You should simply not rely on that order. I think in the current implementation the order is stable as long as you don't delete items. Read
Read: Why is a Dictionary “not ordered”?
try this
foreach (string key in selectedDates.Keys)
{
var item = selectedDates[key];
}
It's simple, loop trough it with a foreach or to get a specific index do:
var date = selectedDates.ElementAt(0).Value;
Let me put together two things for you. Firstly, you can loop or use LINQ to access elements, just as you could do it in a list as well:
var dict = new Dictionary<string, string>();
// loop
foreach (var item in dict)
{
var key = item.Key;
var value = item.Value;
}
// "first" (see below)
var firstItem = dict.First();
However, be aware that what you're referring to as the first item can be pretty much any item in the Dictionary. Dictionaries store elements in any order that is convenient for a lookup (so do sets).
This order is known for some implementations, but lists or arrays might fit better when the order of the elements is important. A Dictionary in .NET is an implementation of a hash table data structure (tree map is another map implementation).
try this :
foreach(var key in selectedDates.Keys)
{
var value = selectedDates[key];
}
Use this overload of Where:
var result = selectedDates.Where((d,i)=>i==0);
Try:
foreach (var date in selectedDates)
{
var item = date.Value;
}

Determine if two collections share at least one element [duplicate]

This question already has an answer here:
Check for any element that exists in two collections
(1 answer)
Closed 9 years ago.
Is there a way to determine if a collection contains at least one element from another collection?
You can use the Any().
var listA = new List<int>();
var listB = new List<int>();
bool hasCommonItem = listA.Any(i => listB.Contains(i));
Moreover, you can write an IEqualityComparer implementation to pass it as a parameter to the Contains() if necessary.
Sure there is.
var sourceCollection = GetSourceCollection();
var otherCollection = GetAnotherCollection();
var hasAtLeastOne = sourceCollection.Intersect(sourceCollection).Any();
I assumed your collections are of the same type: IEnumerable<T> with the same T generic parameter.
It's gonna load whole sourceCollection first, and then fetch one element at a time from otherCollection until first common one is found.
col1.Any(x => col2.Any(y => x==y));

One key and many different values in Dictionary [duplicate]

This question already has answers here:
Multi Value Dictionary?
(10 answers)
Closed 8 years ago.
How can I store many different values in Dictionary under one key?
I have a code here:
Dictionary<string, DateTime> SearchDate = new Dictionary<string, DateTime>();
SearchDate.Add("RestDate", Convert.ToDateTime("02/01/2013"));
SearchDate.Add("RestDate", Convert.ToDateTime("02/28/2013"));
but in Dictionary i learned that only one unique key is allowed, so my code is producing error.
The simplest way is to make a Dictionary of some sort of container, for example
Dictionary<string,HashSet<DateTime>>
or
Dictionary<string,List<DateTime>>
Use Dictionary<string, List<DateTime>>. Access the list by the key, and then add the new item to the list.
Dictionary<string, List<DateTime>> SearchDate =
new Dictionary<string, List<DateTime>>();
...
public void AddItem(string key, DateTime dateItem)
{
var listForKey = SearchDate[key];
if(listForKey == null)
{
listForKey = new List<DateTime>();
}
listForKey.Add(dateItem);
}
You may try using a Lookup Class. To create it you may use Tuple Class:
var l = new List<Tuple<string,DateTime>>();
l.Add(new Tuple<string,DateTime>("RestDate", Convert.ToDateTime("02/01/2013")));
l.Add(new Tuple<string,DateTime>("RestDate", Convert.ToDateTime("02/28/2013")));
var lookup = l.ToLookup(i=>i.Item1);
However, if you need to modify the lookup, you'll have to modify the original list of tuples and update the lookup from it. So, it depends on how often this collection tends to change.
You can use Lookup class if you are using .NET 3.5

A dictionary with multiple entries with the same key [duplicate]

This question already has answers here:
C# dictionary - one key, many values
(15 answers)
Closed 8 years ago.
I need a Dictionary like object that can store multiple entries with the same key. Is this avaliable as a standard collection, or do I need to roll my own?
To clarify, I want to be able to do something like this:
var dict = new Dictionary<int, String>();
dict.Add(1, "first");
dict.Add(1, "second");
foreach(string x in dict[1])
{
Console.WriteLine(x);
}
Output:
first
second
In .NET 3.5 you can use a Lookup instead of a Dictionary.
var items = new List<KeyValuePair<int, String>>();
items.Add(new KeyValuePair<int, String>(1, "first"));
items.Add(new KeyValuePair<int, String>(1, "second"));
var lookup = items.ToLookup(kvp => kvp.Key, kvp => kvp.Value);
foreach (string x in lookup[1])
{
Console.WriteLine(x);
}
The Lookup class is immutable. If you want a mutable version you can use EditableLookup from MiscUtil.
I would recommend doing something like this:
var dict = new Dictionary<int, HashSet<string>>();
dict.Add(1, new HashSet<string>() { "first", "second" });
Dictionary<T,K> does not support such behavior and there's no collection in the base class library providing such behavior. The easiest way is to construct a composite data structure like this:
var data = new Dictionary<int, List<string>>();
As the second parameter you should use a collection which provides the qualities you are looking for, i.e. stable order ⇒ List<T>, fast access HashSet<T>, etc.
You definitely want to use NameValueCollection:
using System.Collections.Specialized;
NameValueCollection nvc = new NameValueCollection();
nvc.Add("pets", "Dog");
nvc.Add("pets", "Rabbit");
Console.WriteLine(nvc["pets"]);
//returns Dog,Rabbit
What you're looking for isn't actually a Dictionary in the traditional sense (see Associative Array).
There's no class, as far as I'm aware, that offers this in the framework (System.Linq.Lookup doesn't expose a constructor), but you could create a class yourself that implements ILookup<TKey, TElement>
You could perhaps use a Dictionary on your primary key, in which each element is a List or other collection on your secondary key. To add an item to your data structure, see if the primary key exists. If not, create a new single-item list with your Value and store it in the dictionary. If the primary key does exist, add your Value to the list that's in the dictionary.

Categories