I am trying to get the dictionary of distinct values using LINQ. I have tried using this:
var roleRefList =
xDocument.Root.Descendants()
.Where(x => x.Name.LocalName.Equals("roleRef") &&
!string.IsNullOrEmpty(Convert.ToString(x.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("roleURI")))) &&
!string.IsNullOrEmpty(Convert.ToString(x.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("href")))))
.Select(l => new {
roleUri = l.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("roleURI")).Value,
href = l.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("href")).Value
})
.Distinct()
.ToDictionary(a => a.roleUri);
The problem here is that when there are duplicate entries in the roleUri
then an error occurs.
I am parsing the XML document and making a dictionary of xElement attributes roleUri
and roleref
if they are present in the xElement.
The other workaround is using a for loop:
Dictionary<string, string> roleRefList = new Dictionary<string, string>();
foreach (XElement element in xDocument.Root.Descendants().Where(x => x.Name.LocalName.Equals("roleRef")))
{
string roelUri = Convert.ToString(element.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("roleURI")));
string href = Convert.ToString(element.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("href")));
if (!string.IsNullOrEmpty(roelUri) && !string.IsNullOrEmpty(href) && !roleRefList.ContainsKey(roelUri))
{
roleRefList.Add(roelUri, href);
}
}
but I want to implement this using LINQ.
You could write your own Distinct
method that would take Func<T,TKey>
as an argument. You can find example of that here: Distinct list of objects based on an arbitrary key in LINQ
With that method you should be able to write:
var roleRefList = xDocument.Root.Descendants().Where(x => x.Name.LocalName.Equals("roleRef") && !string.IsNullOrEmpty(Convert.ToString(x.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("roleURI")))) && !string.IsNullOrEmpty(Convert.ToString(x.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("href")))))
.Select(l => new
{
roleUri = l.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("roleURI")).Value,
href = l.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("href")).Value
}).Distinct(l => l.roleUri).ToDictionary(a => a.roleUri);
Update
Or you can use grouping:
var roleRefList = xDocument.Root.Descendants().Where(x => x.Name.LocalName.Equals("roleRef") && !string.IsNullOrEmpty(Convert.ToString(x.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("roleURI")))) && !string.IsNullOrEmpty(Convert.ToString(x.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("href")))))
.Select(l => new
{
roleUri = l.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("roleURI")).Value,
href = l.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("href")).Value
})
.GroupBy(l => l.roleUri)
.ToDictionary(g => g.Key, g => g.FirstOrDefault());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With