I would like to know how do I declare/initialize a dictionary ?
The below one gives error.
Dictionary<string, List<string>> myD = new Dictionary<string, List<string>>()
{
{"tab1", MyList }
};
List <string> MyList = new List<string>() { "1" };
The error is: A field initializer cannot reference the non-static field, method, or property MyList. It is not List declaration coming in front or later after dictionary.
class MyClass
{
Dictionary<string, List<string>> myD = new Dictionary<string, List<string>>()
{
{"tab1", new List<string> { "1" } },
{"tab2", new List<string> { "1","2","3" } },
{"tab3", new List<string> { "one","two" } }
};
}
As Scott Chamberlain said in his answer:
If these are non static field definitions you can not use the field
initializers like that, you must put the data in the constructor.
class MyClass
{
Dictionary<string, List<string>> myD;
List <string> MyList;
public MyClass()
{
MyList = new List<string>() { "1" };
myD = new Dictionary<string, List<string>>()
{
{"tab1", MyList }
};
}
}
Additionally for Static field
private static List<string> MyList = new List<string>()
{
"1"
};
private static Dictionary<string, List<string>> myD = new Dictionary<string, List<string>>()
{
{"tab1", MyList }
};
If these are non static field definitions you can not use the field initializers like that, you must put the data in the constructor.
class MyClass
{
Dictionary<string, List<string>> myD;
List <string> MyList;
public MyClass()
{
MyList = new List<string>() { "1" };
myD = new Dictionary<string, List<string>>()
{
{"tab1", MyList }
};
}
}
Related
I am having trouble with the syntax of how to get an XUnit Test Method to accept a dictionary as a paramater. This is my code which is broken:
Public static Dictionary<string, string> vals = new Dictionary<string, string> { { "a", "1" }, { "b", "2" }, { "ca", "3" } };
public static object[] dicList = new object[] { vals };
[Theory]
[MemberData(nameof(dicList))]
public void CheckSomething_ReturnsSomething(Dictionary<string, string> values)
{
test stuff...
I am getting an error I understand from the error thrown that I need a return type of
IEnumerable<object[]>
I am unsure of how to achieve this with a dictionary.
Have added some code as suggested: I am still getting an error:
public static Dictionary<string, string> vals = new Dictionary<string, string> { { "a", "1" }, { "b", "2" }, { "ca", "3" } };
public static IEnumerable<object[]> dicList = new List<object[]> { new object[] { vals } };
[Theory]
[MemberData(dicList)] //error here
public void DriverLogon_CheckParams(Dictionary<string, string> values)
{
}
The new error is
error. "Cannot convert from IEnumerable<object[]> To string
The dicList must be an IEnumerable<object[]> like the error message says. This is because one item in the dicList contains all the parameter values for one test (this doesn't matter for your case since you only have one parameter, but it's good to know).
So your dicList becomes a List<object[]> instead of just plain object array:
public static Dictionary<string, string> vals = new Dictionary<string, string> { { "a", "1" }, { "b", "2" }, { "ca", "3" } };
public static IEnumerable<object[]> dicList = new List<object[]> { new object[] { vals } };
I am trying to figure out if there is a way to generalize a function that takes a Hashset of two unrelated objects with similar attributes. I have some sample code below:
private IList<IDictionary<string, string>> BuildDictionary(HashSet<ClassA> ClassA)
{
IList<IDictionary<string, string>> data = new List<IDictionary<string, string>>();
foreach (var a in ClassA)
{
Dictionary<string, string> aDictionary = new Dictionary<string, string>();
aDictionary.Add(a.Code, a.Code + "," + a.Name);
data.Add(aDictionary);
}
return data;
}
private IList<IDictionary<string, string>> BuildDictionary(HashSet<ClassB> ClassB)
{
IList<IDictionary<string, string>> data = new List<IDictionary<string, string>>();
foreach (var b in ClassB)
{
Dictionary<string, string> bDictionary = new Dictionary<string, string>();
bDictionary.Add(b.Code, b.Code + "," + b.Name);
data.Add(bDictionary);
}
return data;
}
Thus as evident from the code, the two classes are not related but they both are in a HashSet and contain similar attributes (code, name). I have tried using the generic T but that failed due to the fact that I don't have the generic class T created. Would there be anyway to get around this issue without creating a new class?
If your source classes are sealed or can't be modified to a common interface, you can use accessors for the parts that are needed, as one might do in most LINQ queries.
Here's an example implementation. Note that toKey() and toMemberValue() could be named more appropriately, but this is enough to replicate what you are doing for any class where you can specify a lambda to retrieve the relevant property, and isn't dependent upon the class necessarily having the same property names so long as the lambda is written accordingly. Main() shows what it would look like to use this method for both cases.
public IList<IDictionary<string, string>> BuildDictionary<T>(HashSet<T> sourceSet, Func<T, string> toKey, Func<T, string> toMemberValue)
{
IList<IDictionary<string, string>> data = new List<IDictionary<string, string>>();
foreach (var element in sourceSet)
{
Dictionary<string, string> newLookup = new Dictionary<string, string>();
newLookup.Add(toKey(element), $"{toKey(element)},{toMemberValue(element)}");
data.Add(newLookup);
}
return data;
}
void Main()
{
HashSet<ClassA> setOfAs = new HashSet<ClassA>(new[] { new ClassA { Code = "foo", Name = "bar" }, new ClassA { Code = "foo2", Name = "bar2" } });
HashSet<ClassB> setOfBs = new HashSet<ClassB>(new[] { new ClassB { Code = "foo", Name = "bar" }, new ClassB { Code = "foo2", Name = "bar2" } });
var lookupOfAs = BuildDictionary(setOfAs, x => x.Code, x => x.Name);
var lookupOfBs = BuildDictionary(setOfBs, x => x.Code, x => x.Name);
}
// Define other methods and classes here
public class ClassA
{
public string Code { get; set; }
public string Name { get; set; }
}
public class ClassB
{
public string Code { get; set; }
public string Name { get; set; }
}
If you own the source code to both types you can implement a common interface.
private IList<IDictionary<string, string>> BuildDictionary<T>(HashSet<T> someHashSetOfTs) where T : ICommon
{
IList<IDictionary<string, string>> data = new List<IDictionary<string, string>>();
foreach (var a in someHashSetOfTs)
{
Dictionary<string, string> aDictionary = new Dictionary<string, string>();
aDictionary.Add(a.Code, a.Code + "," + a.Name);
data.Add(aDictionary);
}
return data;
}
Interface definition
public interface ICommon {
string Code {get; }
string Name {get; }
}
And now apply ICommon to both types ClassA and ClassB.
I have the following code:
class Foo<KType, VType>
{
public KType Key;
public VType Value;
public List<Foo<KType, VType>> Children;
}
class Test
{
public Test()
{
var x = new List<Foo<int, string>>()
{
new Foo<int, string>() {Key = 1, Value = "a", Children = new List<Foo<int, string>>()
{
new Foo<int, string>() {Key = 1, Value = "a"},
new Foo<int, string>() {Key = 2, Value = "b"}
}
},
new Foo<int, string>() {Key = 2, Value = "b"}
};
}
}
It works beautifully in allowing me to have a tree of nested "pairs" of {KType, VType}. However, because I have a List and not a Dictionary, I don't have a way of enforcing that the keys will be unique. How can I construct a tree or chain of dictionaries or the equivalent? I'd like to change the underlying type of "Children" to a dictionary, but that takes a KeyValuePair, which takes only 2 items, a key and a value, and there'd be no room for the grandchildren.
As mentioned by #jdweng, the dictionary could map keys to foos:
class Foo<KType, VType>
{
public VType Value;
public Dictionary<KType, Foo<KType, VType>> Children;
}
class Test
{
public Test()
{
var root = new Foo<int, string>
{
Value = "root",
Children = new Dictionary<int, Foo<int, string>>
{
{
1,
new Foo<int, string>
{
Value = "a",
Children = new Dictionary<int, Foo<int, string>>
{
{1, new Foo<int, string> {Value = "a", Children = null}},
{2, new Foo<int, string> {Value = "b", Children = null}}
}
}
},
{
2,
new Foo<int, string>
{
Value = "b",
Children = null
}
}
}
};
}
}
I have a object structure like so
public class Obj1
{
public string Name {get; set;}
public List<KeyValuePair<int, double>> PairList {get; set;}
}
If I have a list of Obj1, how would I be able to Order that list based on the largest value in Pair list, where key is a particular value. For instance this object.
List<Obj1> foo = new List<Obj1>()
{
new Obj1()
{
Name = "Foo",
PairList = new List<KeyValuePair<int, double>>()
{
new KeyValuePair<int, double>(1,20),
new KeyValuePair<int, double>(2,25),
new KeyValuePair<int, double>(3,30)
}
},
new Obj1()
{
Name = "Bar",
PairList = new List<KeyValuePair<int, double>>()
{
new KeyValuePair<int, double>(1,20),
new KeyValuePair<int, double>(2,60),
new KeyValuePair<int, double>(3,30)
}
},
new Obj1()
{
Name = "Test",
PairList = new List<KeyValuePair<int, double>>()
{
new KeyValuePair<int, double>(1,20),
new KeyValuePair<int, double>(2,35),
new KeyValuePair<int, double>(3,30)
}
}
};
If I want to order by the above list where the Key is 2, I would expect the order of the list to be the following names
Bar
Test
Foo
How can I do this in LINQ?
Try this
var result= foo.OrderByDescending(x => x.PairList[1].Value);
You have to take the max value from PairList and uset it to sort the objects by it.
var result = foo.OrderByDescending(x => x.PairList.Max(v => v.Value));
How would I sort this by a chosen dictionary value in Person?
Example: Order List of "Person" by "cars" value descending.
Is that possible with one of those fancy lambda/linq equations?
public class People
{
List<Person> Persons { get; set; }
}
public class Person
{
public Dictionary<string, string> cars { get; set; }
public Dictionary<string, string> houses { get; set; }
public Dictionary<string, string> banks { get; set; }
}
................
People people = new People();
people.Persons = new List<Person>
{
new Person
{
cars = new Dictionary<string, string> { { "volvo", "340050" }, { "bmw", "50545000" } },
houses = new Dictionary<string, string> { { "mansion", "100040000" },{ "cardboard box", "112" } },
banks = new Dictionary<string, string> { { "swiss", "12500330000" }, { "camen", "12000000" } }
},
new Person
{
cars = new Dictionary<string, string> { { "volvo", "34023200" }, { "bmw", "5003300" } },
houses = new Dictionary<string, string> { { "mansion", "1000330000" },{ "cardboard box", "277" } },
banks = new Dictionary<string, string> { { "swiss", "12500044000" }, { "camen", "12000000" } }
},
new Person
{
cars = new Dictionary<string, string> { { "volvo", "3554000" }, { "bmw", "50023200" } },
houses = new Dictionary<string, string> { { "mansion", "1006600000" },{ "cardboard box", "244" } },
banks = new Dictionary<string, string> { { "swiss", "125000544000" }, { "camen", "12000777000" } }
}
};
EDIT / EXAMPLE RESULT:
The result would be a new or reordered list based on a value contained in the dictionary of each Person
Person -> cars -> { "volvo", "34023200" }
Person -> cars -> { "volvo", "3554000" }
Person -> cars -> { "volvo", "340050" }
The new or reordered List would look exactly like this:
people.Persons = new List<Person>
{
new Person
{
cars = new Dictionary<string, string> { { "volvo", "34023200" }, { "bmw", "5003300" } },
houses = new Dictionary<string, string> { { "mansion", "1000330000" },{ "cardboard box", "277" } },
banks = new Dictionary<string, string> { { "swiss", "12500044000" }, { "camen", "12000000" } }
},
new Person
{
cars = new Dictionary<string, string> { { "volvo", "3554000" }, { "bmw", "50023200" } },
houses = new Dictionary<string, string> { { "mansion", "1006600000" },{ "cardboard box", "244" } },
banks = new Dictionary<string, string> { { "swiss", "125000544000" }, { "camen", "12000777000" } }
},
new Person
{
cars = new Dictionary<string, string> { { "volvo", "340050" }, { "bmw", "50545000" } },
houses = new Dictionary<string, string> { { "mansion", "100040000" },{ "cardboard box", "112" } },
banks = new Dictionary<string, string> { { "swiss", "12500330000" }, { "camen", "12000000" } }
}
};
Here's a nifty trick; basically, a Dictionary can be thought of as a List of KeyValuePair<> objects.
Dictionary<int, string> myDictionary = new Dictionary<int, string>();
foreach(var item in myDictionary)
// item is a KeyValuePair<int, string>, enumerated in order of their insertion into the dictionary
Now that it is in a list, it's easy to sort via LINQ:
Dictionary<int, string> sample = new Dictionary<int, string>
{
{ 1, "Sample" },
{ 2, "Another Sample" }
};
var orderedList = sample.OrderBy(x => x.Value).ToList();
Of course, the bigger problem is why you would need to sort and order a Dictionary - that's not exactly an operation that is really grouped with the concept of a dictionary (it's more for quick access of specific elements via a specified key). The problem description you write about seems odd; you can order the cars for a specific person, but are you trying to find each car from each person ordered by value?
That's easy to do as well:
List<PersonCarDetails> allStuff = new List<PersonCarDetails>();
foreach(var person in persons)
allStuff.AddRange(person.Cars.Select(x => new PersonCarDetails { PersonId = person.Id, CarName = x.Key, CarId = x.Value }).ToList());
// allStuff now contains a list of PersonCarDetails, and then you can order that:
var orderedList = allStuff.OrderBy(x => x.CarId).ToList();
If you mean sort by the number of cars owned by the person
var result = Person.OrderByDescending(x => x.cars.Count);
If you mean sort by the first (sorted by name) car name owned by the person
var result = Person.OrderByDescending(x => x.cars.Keys.OrderBy(y => y.Key).FirstOrDefault());
If you mean sort by the first (sorted by number) car number owned by the person
var result = Person.OrderByDescending(x => x.cars.Keys.OrderBy(y => y.value).FirstOrDefault());
An example output would be good to clarify what actually you want to sort by, since cars is a list, rather than just an element.
Based on the examples you provided this might just do the job for you:
var result = Person.OrderByDescending(x => x.cars.Values.FirstOrDefault());