Как отобразить DataTable строк в DataTable целых чисел в C #, используя встроенную библиотеку? - PullRequest
0 голосов
/ 07 сентября 2018

У меня есть набор DataTables, каждый с набором строк и набором столбцов, все строки. Я ищу лучший способ (т. Е. Самый короткий с codeLength и, возможно, самый эффективный с точки зрения производительности), чтобы сопоставить каждый из этих DataTables с DataTable с целочисленными значениями, чтобы одна и та же строка всегда была представлена ​​одним и тем же целочисленным значением. во всех таблицах, а также в одной и той же таблице (без записи собственных циклов / etc, так как одним из вариантов является циклическое преобразование всех данных и создание целых чисел из строк).

Мой вопрос: есть ли в c # встроенные библиотеки для выполнения этой задачи путем вызова метода?

Предположения: а) Есть тысячи таблиц и миллионы записей в таблицах. б) Решение может быть чувствительным к регистру или нечувствительным.

Принимая такой пример:

DataTableInStrings1.Rows[10]["Column10"] = "val1";
DataTableInStrings2.Rows[2]["Column1"] = "val1";

Ожидаемый короткий код:

DataTable dataTableInIntegers1 = LibIAmAfter.MethodIAmAfter(DataTableInStrings1)
DataTable dataTableInIntegers2 = LibIAmAfter.MethodIAmAfter(DataTableInStrings2)

Ожидаемый результат

dataTableInIntegers1.Rows[10]["Column10"]=12; 
dataTableInIntegers2.Rows[2]["Column1"]=12;

В то время как целое число 12 может быть любым значением. Здесь он выбран случайным образом для иллюстрации цели.

==> Еще один пример, помогающий разобраться в вопросе:

row1InStrings: ("abc","def","abc","zxv","was","morning","def","dr","tr","uy");
row2InStrings: ("abc2","def2","abc3","zxv4","was4","morning2","def2","dr3","tr3","uy");

Пример результата после сопоставления:

row1InIntegers: 1,2,1,3,4,5,2,6,7,8
row2InIntegers: 10,11,12,14,15,16,11,17,18,8

Ответы [ 3 ]

0 голосов
/ 07 сентября 2018

Одним из способов будет использование Dictionary<string, int> для хранения данных ячейки в качестве ключа и целое число сопоставления в качестве значения.

Обратите внимание, что вам не нужно заполнять сопоставление сразу всем набором данных. Пока вы поддерживаете один словарь сопоставлений, вы можете просто заполнять его при доступе к элементам.

Обратите внимание, что это гарантирует только уникальность значения строки, но не обязательно того же значения при последующих запусках (поскольку значения основаны на том, когда был запрошен идентификатор, а не на самой строке).

Что-то вроде этого статического класса с приватным полем и методом доступа должно работать (хотя и не поточно-ориентировано):

public static class Mapper
{
    private static readonly Dictionary<string, int> Mapping = 
        new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);

    public static int GetId(string value)
    {
        int result;

        if (!Mapping.TryGetValue(value, out result))
        {
            result = Mapping.Count + 1;
            Mapping.Add(value, result);
        }

        return result;
    }
}

С помощью этого метода мы можем получать отображения по мере необходимости, а словарь заполняется только по мере необходимости:

DataTable tbl1 = new DataTable("table1");
tbl1.Columns.Add(new DataColumn("col1"));
tbl1.Columns.Add(new DataColumn("col2"));
tbl1.Columns.Add(new DataColumn("col3"));
tbl1.Columns.Add(new DataColumn("col4"));
tbl1.Columns.Add(new DataColumn("col5"));
tbl1.Columns.Add(new DataColumn("col6"));
tbl1.Columns.Add(new DataColumn("col7"));
tbl1.Columns.Add(new DataColumn("col8"));
tbl1.Columns.Add(new DataColumn("col9"));
tbl1.Columns.Add(new DataColumn("col10"));

tbl1.Rows.Add("abc", "def", "abc", "zxv", "was", "morning", "def", "dr", "tr", "uy");
tbl1.Rows.Add("abc2", "def2", "abc3", "zxv4", "was4", "Morning", "def2", "dr3", "tr3", "uy");

// Output mappings, which populates the dictionary     
// only when needed as each mapping is requested
foreach (DataRow row in tbl1.Rows)
{
    Console.WriteLine(string.Join(",", 
        row.ItemArray.Select(item => Mapper.GetId(item.ToString()))));
}

выход

enter image description here

0 голосов
/ 07 сентября 2018

Вы можете использовать детерминированный гид для создания уникального хэша. Более того, вы можете просто использовать само значение в качестве собственного уникального хэша. Я вижу это полезным только в том случае, если по какой-то причине вы не можете показать пользователям исходное значение, но все же хотите найти его в списке. Например, массив паролей.

    [TestMethod]
    public void test_sum_stringchars()
    {
        string tmp = "foobar5";
        Console.WriteLine("Value = " + tmp.ToCharArray().Sum(x => x));
        // 686
        Console.WriteLine("Value = " + ToGuidKey(tmp));
        // 79ceeb8d

        tmp = "foobar6";
        Console.WriteLine("Value = " + tmp.ToCharArray().Sum(x => x));
        // 687
        Console.WriteLine("Value = " + ToGuidKey(tmp));
        // f1f08c51

        tmp = "goobar5";
        Console.WriteLine("Value = " + tmp.ToCharArray().Sum(x => x));
        // 687
        Console.WriteLine("Value = " + ToGuidKey(tmp));
        // f7da9f42

        tmp = "foocar5";
        Console.WriteLine("Value = " + tmp.ToCharArray().Sum(x => x));
        // 687
        Console.WriteLine("Value = " + ToGuidKey(tmp));
        // 7698c7ec
    }
    public static Guid ToGuid(string src)
    {
        byte[] stringbytes = System.Text.Encoding.UTF8.GetBytes(src);
        byte[] hashedBytes = new System.Security.Cryptography
            .SHA1CryptoServiceProvider()
            .ComputeHash(stringbytes);
        Array.Resize(ref hashedBytes, 16);
        return new Guid(hashedBytes);
    }
    public static string ToGuidKey(string src)
    {
        return ToGuid(src).ToString().Split('-').First();
    }
0 голосов
/ 07 сентября 2018

Суммируйте значение char каждого значения в строке. Обратите внимание, что суммирование значений символов не гарантирует уникальности каждого значения. Вы можете создать несколько одинаковых числовых значений несколькими способами.

    [TestMethod]
    public void test_sum_stringchars()
    {
        string tmp = "foobar5";
        Console.WriteLine("Value = " + tmp.ToCharArray().Sum(x => x));
        // 686

        tmp = "foobar6";
        Console.WriteLine("Value = " + tmp.ToCharArray().Sum(x => x));
        // 687

        tmp = "goobar5";
        Console.WriteLine("Value = " + tmp.ToCharArray().Sum(x => x));
        // 687

        tmp = "foocar5";
        Console.WriteLine("Value = " + tmp.ToCharArray().Sum(x => x));
        // 687
    }
...