?
Solved

List<Dictionary<string, string>> how do I get a set of distinct columns?

Posted on 2013-06-03
8
Medium Priority
?
1,177 Views
Last Modified: 2013-06-05
I currently have a List<Dictionary<string, string>>, and I need distinct columns.

This collection has many values about a user: firstname, lastname, email, etc.  Not all values are distinct in the entire dictionary, but I need the distinct values for certain columns, like mentioned above.

so:
bob, smith, bob@gmail.com, 5
bob, smith, bob@gmail.com, 6
karen, smith, karen@gmail.com, 7
karen, smith, karen@gmail.com, 8

I want
bob, smith, bob@gmail.com
karen, smith, karen@gmail.com

so basically a distinct, but only for certain columns, but I want the results to also be a List<Dictionary<string, string>>.
0
Comment
Question by:jackjohnson44
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
8 Comments
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 39217387
Hi jackjohnson44;

The List<Dictionary<string, string>> can have many dictionaries in the list, you want to have each dictionary  in itself to have Distinct column values?

In the Dictionary you have the Key and Value as you defined it to both be of type string. Is the Key to column and the value the column value which you want to be Distinct?

Can you also show what values will be in a typical key and what value is in the Value of that dictionary entry.
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 39218292
i assume that each dictionary in the list is user's properties (key -> property name, value -> property value).
if u want to distincy by columns, u need to specify the columns which u want to distinct, then using linq u can group the dictionary by the property values.
0
 

Author Comment

by:jackjohnson44
ID: 39220037
Hi guys,
Sorry, I am not following your questions.

I have a list of dictionaries which are all the same.  In this instance, I only need some of the columns.

MyDictList[0]["FirstName"] = "bob"
MyDictList[0]["LastName"] = "smith"
MyDictList[0]["OtherColumn"] = "1"

MyDictList[1]["FirstName"] = "bob"
MyDictList[1]["LastName"] = "smith"
MyDictList[1]["OtherColumn"] = "2"

MyDictList[2]["FirstName"] = "Karen"
MyDictList[2]["LastName"] = "smith"
MyDictList[2]["OtherColumn"] = "1"

MyDictList[3]["FirstName"] = "Karen"
MyDictList[3]["LastName"] = "smith"
MyDictList[3]["OtherColumn"] = "2"

I want
newDict[0]["FirstName"] = "bob"
newDict[0]["LastName"] = "smith"
newDict[1]["FirstName"] = "Karen"
newDict[1]["LastName"] = "smith"

To state it another way.  Start with my List<Dictionary<string, string>>.  Remove all columns that I am not using.  After that, do a distinct.

If this were sql
select distinct firstname, lastname from x


I can do this with linq, but it changes my output object.
0
Visualize your virtual and backup environments

Create well-organized and polished visualizations of your virtual and backup environments when planning VMware vSphere, Microsoft Hyper-V or Veeam deployments. It helps you to gain better visibility and valuable business insights.

 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 39220075
I can do this with linq, but it changes my output object.
So you want the existing list of dictionaries to reflect the change? You don't want to create a new object as a result of LINQ, correct?
0
 

Author Comment

by:jackjohnson44
ID: 39220091
I want the output to be List<Dictionary<string, string>>.  It will have less dictionary items.  I don't want to create a "new object" meaning a new anonymous type.  I have a ton of functions that take in List<Dictionary<string, string>>.

to make this extremely simple:
MyDictList[0]["FirstName"] = "bob"
MyDictList[0]["LastName"] = "smith"
MyDictList[0]["OtherColumn"] = "1"

MyDictList[1]["FirstName"] = "bob"
MyDictList[1]["LastName"] = "smith"
MyDictList[1]["OtherColumn"] = "2"

I want the result to be
x[0]["FirstName"] = "bob"
x[0]["LastName"] = "smith"

List<Dictionary<string, string>> x = getDistinctFirstLastName(mydictlist);
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 39220200
I want the output to be List<Dictionary<string, string>>.  It will have less dictionary items.
We get that. Do you want the output to be the original List<Dictionary<string, string>>, or should it be a new, separate instance of a List<Dictionary<string, string>>?
0
 

Author Comment

by:jackjohnson44
ID: 39220273
A new one.  It will have less columns, so it would have to be different.

If I wanted to go from a list<dict<string,string>> to an anon object, I would use the code below.  I need the output to be list<dict<string,string>>.


            var dataRowsSelectedAccess = (from dr in dataRows
                                          select new
                                                     {
                                                         LastName = dr["LastName"].ToSafeString(),
                                                         FirstName = dr["FirstName"].ToSafeString(),
                                                         EmailAddress = dr["EmailAddress"].ToSafeString(),
                                                         LocationAccess = dr["LocationAccess"].ToSafeString(),
                                                         UserType = dr["UserType"].ToSafeString(),
                                                         ManagingUser = dr["ManagingUser"].ToSafeString(),
                                                         AdminApprover = dr["AdminApprover"].ToSafeString(),
                                                         Title = dr["Title"].ToSafeString(),
                                                         Profile = dr["Profile"].ToSafeString(),
                                                         LastLogin = dr["LastLogin"].ToSafeString()
                                                     }).Distinct().ToList();
0
 
LVL 75

Accepted Solution

by:
käµfm³d   👽 earned 2000 total points
ID: 39220454
Try the following:

string[] relevantKeys = { "FirstName", "LastName" };

var dictsWithBothKeys = MyDictList.Where(dict => relevantKeys.All(key => dict.ContainsKey(key)));
var dictsWithJustBothKeys = dictsWithBothKeys.Select(dict => dict.Keys.Where(key => relevantKeys.Contains(key))
                                                                      .ToDictionary(key => key, key => dict[key]));
var distinctDicts = dictsWithJustBothKeys.Distinct(new DictComparer(relevantKeys));

Open in new window


class DictComparer : IEqualityComparer<Dictionary<string, string>>
{
    private IEnumerable<string> _keys;

    public DictComparer(IEnumerable<string> keys)
    {
        this._keys = keys;
    }

    public bool Equals(Dictionary<string, string> x, Dictionary<string, string> y)
    {
        foreach (string key in this._keys)
        {
            if (!x.ContainsKey(key) ||
                !y.ContainsKey(key) ||
                 x[key] != y[key])
            {
                return false;
            }
        }

        return true;
    }

    public int GetHashCode(Dictionary<string, string> obj)
    {
        return 0;
    }
}

Open in new window


You might need to adjust the implementation of GetHashCode above. It seemed to work with the data you provided, but that was a small sampling.
0

Featured Post

The Orion Papers

Are you interested in becoming an AWS Certified Solutions Architect?

Discover a new interactive way of training for the exam.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…
Suggested Courses

764 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question