Convert Dictionary<string, object> to a collection of objects with key - c#

Is there a way to convert Dictionary<string, obj> to collection of objects such that each single object in the collection includes the key as another property
Here is the class def for obj
class someclass
{
string property1;
string property2;
}
After conversion, I am expecting each object in the collection to be like
obj.property1
obj.property2
obj.Key
I have been struggling with this since along time and I seek some help. any ideas?
thanks in advance.

Something like
var myCollection = from de in myDictionary
select new
{
de.Value.property1,
de.Value.property2,
de.Key
}.ToList(); // or .ToArray()
should do the trick.
That will return a List of a new anonymous type with the properties you requested.

You could also(in addition to the anonymous type apporach) use a List<Tuple<string, string, string>>:
var list= dictionary
.Select(kv => Tuple.Create(kv.Value.property1, kv.Value.property2, kv.Key))
.ToList();
foreach(var item in list)
{
Console.WriteLine("property1:{0 property2:{1} key:{2}"
, item.Item1
, item.Item2
, item.Item3);
}
The advantage over an anonymous type is that you can return the Tuple easily from a method.
Edit: A third option(my favorite) is simply to create instances of a class that you've declared somewhere. That's the ideal way. I don't know why i thought that you want a class "on the fly".
class someOtherClass
{
public string property1{ get; set; };
public string property2{ get; set; };
public string Key{ get; set; };
}
List<someOtherClass> objects = dictionary
.Select(kv => new someOtherClass(){
property1 = kv.Value.property1,
property2 = kv.Value.property2,
Key = kv.Key
})
.ToList();

You may use anonymous type if you don't want to store the result like this:
In case you just wana use it as datasource for example.
var res = myDictionary.Select(pair => new { pair.Key, pair.Value.Property1, pair.Value.Property2 });

The other answers are good, so this is just a supplement.
You could use arrays of Length three:
var arrays = myDictionary
.Select(kv => new[] { kv.Value.property1, kv.Value.property2, kv.Key, });
Or you could write a new class
class SomeclassAndKey
{
public string property1;
public string property1;
public string Key;
}
and then say
var someclassAndKeys = myDictionary
.Select(kv => new SomeclassAndKey { property1 = kv.Value.property1, property2 = kv.Value.property2, Key = kv.Key, });
In each case you could append .ToList() if you wanted not to defer enumeration and get a full List<> out.

Related

Converting a distinct list to dictionary not working

I'm trying to convert a list of objects to a dictionary using the following code:
var MyDictionary = MyList.Distinct().ToDictionary(i => i.ObjectId, i => i);
I know that a dictionary should not contain duplicate elements, hence the .Distinct(). Yet I still get the following Exception whenever there's a duplicate element:
An item with the same key has already been added.
MyList is a list of MyObject that looks like this:
public class MyObject{
public string ObjectId { get; set; }
public string FName { get; set; }
public string LName { get; set; }
}
Is there a better way to create a dictionary from a list of objects ? or am I doing something wrong?
If you want to compare on the ObjectId, you'll need to pass in a custom comparer to .Distinct(). You can do so like this:
class MyObjectComparer : IEqualityComparer<MyObject>
{
public bool Equals(MyObject x, MyObject y)
{
return x.ObjectId == y.ObjectId;
}
public int GetHashCode(MyObject obj)
{
return obj.ObjectId.GetHashCode();
}
}
var MyDictionary = MyList
.Distinct(new MyObjectComparer())
.ToDictionary(i => i.ObjectId, i => i);
You could use Group by and then select first from the List as below:
var MyDictionary = MyList.GroupBy(i => i.ObjectId, i => i).ToDictionary(i => i.Key, i => i.First());
Distinct works using the objects built in Equals and GetHashCode methods by default but your dictionary works only over the id. You need to pass in a IEqualityComparer in to distinct that does the comparison on Id to test if items are equal or make MyObject implment Equals and GetHashCode and have that compare on the Id.

Deserialize json array of dictionaries in c#

I have an array of dictionaries that I've created in javascript. After serializing to json I get the following string :
"[{\"key\":\"60236\",\"value\":\"1\"},{\"key\":\"60235\",\"value\":\"gdsfgdfsg\"},{\"key\":\"60237\",\"value\":\"1\"}]"
I am having a hard time getting this deserialized into either a list or dictionary in c#.
I've tried:
Dictionary<int, string> values = JsonConvert.DeserializeObject<Dictionary<int, string>>(Model.Json);
but that doesn't work.
There are several ways that you can extract your key/value pairs to construct a dictionary:
var dict = "[{\"key\":\"60236\",\"value\":\"1\"},
{\"key\":\"60235\",\"value\":\"gdsfgdfsg\"},
{\"key\":\"60237\",\"value\":\"1\"}]";
Use List<KeyValuePair<int, string>>
var dictionary = JsonConvert.DeserializeObject<List<KeyValuePair<int, string>>>(dict)
.ToDictionary(x => x.Key, y => y.Value);
Use a custom object that represents your pairs and then create a dictionary from your collection.
var output = JsonConvert.DeserializeObject<List<Temp>>(dict);
var dictionary = output.ToDictionary(x => x.Key, y => y.Value);
public class Temp
{
public int Key { get; set; }
public string Value { get; set; }
}
Finally, if you're uncomfortable with using a custom "throwaway" object just for deserialization, you can take a tiny performance hit and use dynamic instead.
var dictionary = JsonConvert.DeserializeObject<List<dynamic>>(dict)
.ToDictionary (x => (int)x.key, y => (string)y.value);
what i suggest is for try to see what actually your json represent. You can create a class here on Json2CSharp and the use this class/List of this class (depend on whether your json is in the form of array or simple class object).
Just pass type to JsonConvert.DeserializeObject class type part. for example
var output = JsonConvert.DeserializeObject<List<Class>>(json);
In your case is it just an array of Temp class
public class Temp
{
public string key { get; set; }
public string value { get; set; }
}
Sp all you need is :-
var output = JsonConvert.DeserializeObject<List<Temp>>(json);
The you can convert this list to dictionary as suggested in other answer:-
var dictionary = output.ToDictionary(x => x.Key, y => y.Value);
This always help me out. Hope it help you too.

Converting complex object to dictionary<string,string>

I need to convert a dto object class like this :
public class ComplexDto
{
public ComplexDto()
{
ListIds = new List<ListIdsDto>();
}
public string Propertie1 { get; set; }
public string Propertie2 { get; set; }
public IList<int> ListIds { get; set; }
}
to a dictionary<string,string>.
This is just some class example, this class will be used as json object like this:
{"Propertie1":"ss","Propertie2":"","ListIds":[1,2,3]}
I need to pass this object to a FormUrlEncodedContent(dictionary) as dictionary of strings.
I have this :
var data = new Dictionary<string, string>();
data[string.Empty] = ComplexDto.ToJson();
And I would like to transform the ComplexDto.ToJson() or the ComplexDto object to a Dictionary string, string.
Any Ideas ?
Assuming that you have a collection with some ComplexDto instances like:
List<ComplexDto> complexDtoList = ...;
and you expect that there are duplicate keys which would cause an exception(otherwise you could have used a dictionary in the first place).
You can use Enumerable.GroupBy to get unique keys. Then you have to decide what you want to do with the 1-n Propertie2-strings per group. One way is to use String.Join to concat all with a separator:
Dictionary<string, string> result = complexDtoList
.GroupBy(dto => dto.Propertie1)
.ToDictionary(
p1Group => p1Group.Key,
p1Group => string.Join(",", p1Group.Select(dto => dto.Propertie2)));
You could also build a Dictionary<string, List<string>> and use p1Group.Select(dto => dto.Propertie2).ToList() as value.

KeyValuePair in Lambda expression

I am trying to create a KeyValue pair collection with lambda expression.
Here is my class and below that my lambda code. I failed to create the KeyValuePair.
I want to get a collection of KeyValuePair of Id, IsReleased for the
comedy movies. I put those KeyValuePair in HashSet for quick search.
public class Movie{
public string Name{get;set;}
public int Id{get;set;}
public bool IsReleased{get;set;}
//etc
}
List<Movie> movieCollection=//getting from BL
var movieIdReleased= new
HashSet<KeyValuePair<int,bool>>(movieCollection.Where(mov=> mov.Type== "comedy")
.Select(new KeyValuePair<int,bool>(????));
You should pass lambda into that .Select method, not just expression:
.Select(movie => new KeyValuePair<int,bool>(movie.Id, movie.IsReleased))
hope that helps!
//.Select(new KeyValuePair<int,bool>(????));
.Select(movie => new KeyValuePair<int,bool>()
{ Key = movie.Id, Value = movie.IsReleased} );
var comedyMovies = movieCollection
.Where(mc => "comedy".Equals(mc.Type, StringComparison.OrdinalIgnoreCase))
.Select(mc => new KeyValuePair<int, bool>(mc.Id, mc.IsReleased));
var distinctComedyMovies = new HashSet<KeyValuePair<int,bool>>(comedyMovies);

automapper map dynamic object

I am working with Automapper and need to achieve the following mapping but not sure how it can be done.
I want to map a Dictionary object to a dynamic object, so that the key is the property on the object and the value of the dictionary is the value of property in dynamic object.
Can this be achieve with automapper and if so, how?
You can simply get Dictionary from ExpandoObject and fill it with original dictionary values
void Main()
{
AutoMapper.Mapper.CreateMap<Dictionary<string, object>, dynamic>()
.ConstructUsing(CreateDynamicFromDictionary);
var dictionary = new Dictionary<string, object>();
dictionary.Add("Name", "Ilya");
dynamic dyn = Mapper.Map<dynamic>(dictionary);
Console.WriteLine (dyn.Name);//prints Ilya
}
public dynamic CreateDynamicFromDictionary(IDictionary<string, object> dictionary)
{
dynamic dyn = new ExpandoObject();
var expandoDic = (IDictionary<string, object>)dyn;
dictionary.ToList()
.ForEach(keyValue => expandoDic.Add(keyValue.Key, keyValue.Value));
return dyn;
}
Here's en example, but if you drop a comment or elaborate your post it could be more descriptive. Given this class:
class Foo
{
public Foo(int bar, string baz)
{
Bar = bar;
Baz = baz;
}
public int Bar { get; set; }
public string Baz { get; set; }
}
You can create a dictionary of its public instance properties and values this way:
var valuesByProperty = foo.GetType().
GetProperties(BindingFlags.Public | BindingFlags.Instance).
ToDictionary(p => p, p => p.GetValue(foo));
If you want to include more or different results, specify different BindingFlags in the GetProperties method. If this doesn't answer your question, please leave a comment.
Alternatively, assuming you're working with a dynamic object and anonymous types, the approach is similar. The following example, clearly, doesn't require the class Foo.
dynamic foo = new {Bar = 42, Baz = "baz"};
Type fooType = foo.GetType();
var valuesByProperty = fooType.
GetProperties(BindingFlags.Public | BindingFlags.Instance).
ToDictionary(p => p, p => p.GetValue(foo));

Categories