Какую структуру данных следует использовать для сопоставления трех «старых» значений с тремя «новыми» значениями? - PullRequest
1 голос
/ 14 марта 2019

Я пытаюсь выяснить, какую структуру данных имеет смысл представлять мои данные. Я работаю над инструментом C #, который будет обновлять имена определенного набора категорий, подкатегорий и подкатегорий. Вот некоторые примеры данных:

OldCategory | OldSubCategory | OldSubSubCategory | NewCategory           | NewSubCategory | NewSubSubCategory
-------------------------------------------------------------------------------------------------------------
Hardware    | Display        | Broken            | HD-Hardware           | Display        |
Hardware    | Display        | Request upgrade   | Requests              | Hardware       | Display 
Software    | Excel          | Error message     | HD-Software           | Excel          | General Error
Software    | Excel          | How Do I          | HD-Software           | Excel          | Training
Software    | Excel          | Plug-in           | HD-SoftwareExtensions | Excel          |

Как видите, я не могу просто обновить каждый OldCategory до соответствующего NewCategory. Данные построены так, что каждая комбинация Category, SubCategory и SubSubCategory является уникальным значением. Например, Hardware | Display | Request upgrade будет сопоставлен с Requests | Hardware | Display.

Как мне сопоставить комбинацию трех старых значений с комбинацией трех новых значений?

Я подумывал об использовании структуры Dictionary<Tuple<string, string, string>, Tuple<string, string, string>>, но она кажется ужасно многословной и потенциально может сбить с толку других разработчиков или мою будущую личность. Любые предложения для более четкого представления моих данных?

Ответы [ 3 ]

1 голос
/ 14 марта 2019

Я бы предложил пойти по тому же маршруту, что и вы, т.е.

Dictionary<Tuple<string, string, string>, Tuple<string, string, string>>

С новым ValueTuple вы можете использовать более лаконичный синтаксис, чтобы сделать это

var tbl = new Dictionary<(string, string, string), (string, string, string)>();
var newVal = tbl[("Hardware", "Display", "Request upgrade")];

Вы также можете использовать имена для полей кортежей, как показано ниже:

var tbl = new Dictionary<(string Cat, string SubCat, string SubSubCat), (string Cat, string SubCat, string SubSubCat)>();

Если вам нужна большая гибкость, контроль или функции, вы можете использовать класс для этого, как показано ниже

class CatInfo : Tuple<string, string, string> {
    public string Category => Item1;
    public string SubCategory => Item2;
    public string SubSubCategory => Item3;

    public CatInfo(string cat, string subCat, string subSubCat) : base(cat, subCat, subSubCat) { }
}

Если дляпо какой-то причине вы не можете создать подкласс от Tuple или хотите получить чуть более высокую производительность, тогда вы можете просто создать неизменяемую структуру, как показано ниже

struct CatInfo {
    public string Category { get; }
    public string SubCategory { get; } 
    public string SubSubCatergory { get; }

    public CatInfo(string cat, string subCat, string subSubCat) {
        Category = cat;
        SubCategory = subCat;
        SubSubCatergory = subSubCat;
    }

    public bool Equals(CatInfo other) {
        return string.Equals(Category, other.Category) && string.Equals(SubCategory, other.SubCategory) && string.Equals(SubSubCatergory, other.SubSubCatergory);
    }

    public override bool Equals(object obj) {
        if (obj is null)
            return false;
        return obj is CatInfo info && Equals(info);
    }

    public override int GetHashCode() {
        unchecked {
            int hashCode = (Category != null ? Category.GetHashCode() : 0);
            hashCode = (hashCode * 397) ^ (SubCategory != null ? SubCategory.GetHashCode() : 0);
            hashCode = (hashCode * 397) ^ (SubSubCatergory != null ? SubSubCatergory.GetHashCode() : 0);
            return hashCode;
        }
    }

    public static bool operator ==(CatInfo info1, CatInfo info2) {
        return info1.Equals(info2);
    }

    public static bool operator !=(CatInfo info1, CatInfo info2) {
        return !(info1 == info2);
    }
}
1 голос
/ 14 марта 2019

Вот пример того, о чем я говорил в комментариях:

public class Category : IEquatable<Category>
{
    public string MainCategory { get; set; }
    public string SubCategory { get; set; }
    public string SubSubCategory { get; set; }


    private string GetCharacterizer()
    {
        return $"{MainCategory}#{SubCategory}#{SubSubCategory}";
    }

    public override int GetHashCode()
    {
        return GetCharacterizer().GetHashCode();
    }

    public bool Equals(Category other)
    {
        if (other == null)
        {
            return false;
        }
        return GetCharacterizer().Equals(other.GetCharacterizer());
    }

    public override bool Equals(object other)
    {
        if (!(other is Category catOther))
        {
            return false;
        }

        return Equals(catOther);
    }
}

Тогда вы бы создали Dictionary<Category, Category>

0 голосов
/ 14 марта 2019

Создание класса кажется мне лучшим вариантом. Таким образом, вы можете создать конструктор и иметь методы. Э.Г.

public CategoryClass{
    string category;
    string subCategory;
    string subSubCategory;
}

А затем вы можете поместить их в словарь:

static void Main(string[] args)
{
    CategoryClass oldCategory = new CategoryClass();
    CategoryClass newCategory = new CategoryClass();
    Dictionary<CategoryClass, CategoryClass> dict = new Dictionary<CategoryClass, CategoryClass>();
}

... или другой объект.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...