6
\$\begingroup\$

I have a large C# Dictionary of string keys and boolean values. Background on the reason for it is this: my program builds up a bunch of the same objects from two different sources, and then compares all the properties to see if there are any disparates. But I want to ignore the differences where I know one source hasn't exposed that property for comparison, so I have this array that lists the properties that are actually 'gathered'.

Then when filtering the differences before user display, I ask if(!gathered[prop]) and remove it in that case. It would throw an exception if I hadn't defined a case for the property, and I don't want to ignore that as it may just mean I neglected to specify if it was or wasn't gathered.

    public Dictionary<string, bool> TPORGatheredData = new Dictionary<string,bool>()
    {
        // Represents fields that are actually retrieved from TP data
        { "Reference", true },
        { "Title", true },
        { "Status", true },
        { "Status.State", true },
        { "OriginatorName", true },
        { "InvestigatorName", true },
        { "ManagerName", true },
        { "ObservedOn", true },
        { "RaisedOn", true },
        { "ClosedOn", true },
        { "Project", true },
        { "VariantObservedOn", true },
        { "SoftwareVersionObserved", true },
        { "AreaObservedOn", true },
        { "StageObservedOn", true },
        { "VariantAppliedTo", true },
        { "AreaAppliedTo", true },
        { "FaultClassification", true },
        { "Type", true },
        { "SecurityClassification", true },
        { "CommercialClassification", true },
        { "SecurityGroup", true },
        { "SafetyRelated", true },
        { "Description", false },
        { "Recommendations", true },
        { "Recommendations.PointNumber", true },
        { "Recommendations.Id", true },
        { "Recommendations.Type", true },
        { "Recommendations.RecommendationText", true },
        { "ClosureText", true },
    };

The problem with this is that the value of false is quite significant. How could I differentiate the false from the true here?

Two options I can think of:

  1. I could tab align all the values but this looks ugly as the farthest extent they need to go for alignment is a bit too far to easily see which value is for which key.

  2. assume if there's no key then the value is true (although that depends on the context making this a suitable option, and as it stands in my case not having the value may be an indicator of a field that needs checking to see if it is or isn't handled).

\$\endgroup\$
  • 2
    \$\begingroup\$ We need some more context to know how best to help. What is this dictionary used for? Where/how is it modified? My gut reaction seeing the dictionary defined like that is that you should be using a bitmask with an inverted meaning, i.e., switching TPORGatheredData to instead represent ignored data, so your value only sets the flag for Description. \$\endgroup\$ – Dan Lyons Oct 3 '13 at 17:57
  • \$\begingroup\$ Updated the question @DanLyons \$\endgroup\$ – deed02392 Oct 4 '13 at 10:20
8
\$\begingroup\$

Is this more like what you're after?

var TPORGatheredData = new[]
        {
            // Add all values in the logical order that you want them
            "Reference",
            "Title",
            "Status",
            "Status.State",
            //...omitted for brevity
            "Description",
            "ClosureText"

        }.ToDictionary(x=>x,x=>true);

        // This is significant
        TPORGatheredData["Description"] = false;
\$\endgroup\$
6
\$\begingroup\$

Dictionaries don't preserve the order of their entries, so list all keys with false values first, then all keys with true values. I would also sort the keys alphabetically within each group.

// Represents fields that are actually retrieved from TP data
public Dictionary<string, bool> TPORGatheredData = new Dictionary<string,bool>()
{
    // Entries with a false value...
    { "Description", false },

    // Entries with a true value...
    { "AreaAppliedTo", true },
    { "AreaObservedOn", true },
    { "ClosedOn", true },
    { "ClosureText", true },
    { "CommercialClassification", true },
    { "FaultClassification", true },
    { "InvestigatorName", true },
    { "ManagerName", true },
    { "ObservedOn", true },
    { "OriginatorName", true },
    { "Project", true },
    { "RaisedOn", true },
    { "Recommendations", true },
    { "Recommendations.Id", true },
    { "Recommendations.PointNumber", true },
    { "Recommendations.RecommendationText", true },
    { "Recommendations.Type", true },
    { "Reference", true },
    { "SafetyRelated", true },
    { "SecurityClassification", true },
    { "SecurityGroup", true },
    { "SoftwareVersionObserved", true },
    { "StageObservedOn", true },
    { "Status", true },
    { "Status.State", true },
    { "Title", true },
    { "Type", true },
    { "VariantAppliedTo", true },
    { "VariantObservedOn", true },
};
\$\endgroup\$
  • 1
    \$\begingroup\$ But this means that entries that are logically related would be far away. \$\endgroup\$ – svick Oct 3 '13 at 18:25
1
\$\begingroup\$

Given the update...

Since you have a stated requirement of showing properties which do not exist in the collection anyways, then why bother adding entries for properties you want to show at all?

I would only build a collection of the ignored properties, and then check if the collection contains the property during filtering. As such, that if (!gathered[prop]) check instead turns into a if(filter.ContainsKey(prop)) (if still using an IDictionary) or if(filter.Contains(prop)) (for any other collection type).

I would also suggest using a simpler collection like List<T> or a string array, because the set of ignored properties seems to be really small (only one in your example). The performance of dictionary lookup versus list traversal will be insignificant at that size, and it seems more natural to have a collection of names than name/(unused) pairs.

\$\endgroup\$
  • \$\begingroup\$ This is a filter of what properties are gathered for two List<object>s. Both created their Lists from different sources. If one of those sources doesn't return a property eg 'Description', then I want to make sure before I complain to the user about differences, I don't waste their time with a difference that one source said "" when the other said "foo bar" (because obviously the source not gathering it says ""). If I don't have an exhaustive list, I run the risk of having neglected to specify a certain property which might get added elsewhere in the code and not in this gathered list. \$\endgroup\$ – deed02392 Oct 4 '13 at 19:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.