C# Dynami c Dictionary - Выбор случайного значения из Dynami c Object - PullRequest
1 голос
/ 04 февраля 2020

Я изучал динамические c словари как потенциальное решение для связывания нескольких строк с одной строкой 'ID'. Что мне нужно сделать, так это назначить последовательность из 4-буквенных текстовых строк для клавиши, которая также является 4-буквенной текстовой строкой (каждая строка уникальна с диапазоном AAAA-ZZZZ).

Ключи 4-буквенные текстовые строки, такие как: "AAAA", "AAGB" и др. c. Каждая клавиша может содержать несколько 4-буквенных текстовых строк: «ACFE», «AAFE» и т. Д. c.

Цель состоит в том, чтобы выбрать ключ и затем случайным образом выбрать одно из значений динамического c внутри Это. Моя текущая настройка для тестирования выглядит следующим образом:

// Dynamic objects
dynamic d1 = new System.Dynamic.ExpandoObject();  
dynamic d2 = new System.Dynamic.ExpandoObject();
dynamic d3 = new System.Dynamic.ExpandoObject();

var dict = new Dictionary<string, dynamic>();

// Assign dynamic objects to the Dictionary Key
dict["AAAA"] = d1;
dict["AAGB"] = d2;
dict["ABDA"] = d3;

// Populate the dynamic object with the value(s)
dict["AAAA"].FooBar = new { i1 = "ACFE", i2 = "AAFE", i3 = "CAED", i4 = "HSGB" };
dict["AAGB"].FooBar = new { i1 = "ZZZZ", i2 = "XXXX", i3 = "CAED", i4 = "HSGB" };
dict["ABDA"].FooBar = new { i1 = "YYYY", i2 = "WWWW", i3 = "CAED", i4 = "HSGB" };

string newName = dict["ABDA"].FooBar.i1;
return newName;

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

Ответы [ 4 ]

3 голосов
/ 04 февраля 2020

В вашем случае, если вы уже знаете типы ключей и значений, вам, вероятно, следует использовать словарь с расширяемой коллекцией в качестве значения. Соответствующий тип -

Dictionary<string, List<string>>

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

1 голос
/ 04 февраля 2020

Если вы хотите неизменную коллекцию (вы не собираетесь добавлять ее в коллекцию после создания коллекции), используйте поиск. Если вам нужно иметь возможность добавлять / удалять записи, используйте словарь. Я включил пример использования IGrouping, но это самый медленный поиск, так как вам нужно выполнять итерацию до тех пор, пока вы не найдете ключ, но очень эффективный, если вам нужно итерировать все ключи так, как вы хотите получить случайную строку для каждого key.

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

var values = new[] {
    new KeyValuePair<string,string> ("AAAA","ACFE"),
    new KeyValuePair<string,string> ("AAAA","AAFE"),
    new KeyValuePair<string,string> ("AAAA","CAED"),
    new KeyValuePair<string,string> ("AAAA","HSGB"),

    new KeyValuePair<string,string> ("AAGB","ZZZZ"),
    new KeyValuePair<string,string> ("AAGB","XXXX"),
    new KeyValuePair<string,string> ("AAGB","CAED"),
    new KeyValuePair<string,string> ("AAGB","HSGB"),

    new KeyValuePair<string,string> ("ABDA","YYYY"),
    new KeyValuePair<string,string> ("ABDA","WWWW"),
    new KeyValuePair<string,string> ("ABDA","CAED"),
    new KeyValuePair<string,string> ("ABDA","HSGB"),
};
// Convert array to a Lookup
var lookup=values.ToLookup(k=>k.Key, v=>v.Value);

// Retrieve random string from entry "AAAA"
var entry = lookup["AAAA"];
var rand = new Random();
var max = entry.Count();
var ans = entry.Skip(rand.Next(max)).First();

Вот пример использования Dictionary<string,List<string>>:

var values = new[] {
    new KeyValuePair<string,string> ("AAAA","ACFE"),
    new KeyValuePair<string,string> ("AAAA","AAFE"),
    new KeyValuePair<string,string> ("AAAA","CAED"),
    new KeyValuePair<string,string> ("AAAA","HSGB"),

    new KeyValuePair<string,string> ("AAGB","ZZZZ"),
    new KeyValuePair<string,string> ("AAGB","XXXX"),
    new KeyValuePair<string,string> ("AAGB","CAED"),
    new KeyValuePair<string,string> ("AAGB","HSGB"),

    new KeyValuePair<string,string> ("ABDA","YYYY"),
    new KeyValuePair<string,string> ("ABDA","WWWW"),
    new KeyValuePair<string,string> ("ABDA","CAED"),
    new KeyValuePair<string,string> ("ABDA","HSGB"),
};
//Convert array to Dictionary<string,List<String>>
var dict = values.GroupBy(k=>k.Key)
  .ToDictionary(k=>k.Key,v=>v.Select(kvp=>kvp.Value).ToList());

// Retrieve random string from entry "AAAA"
var entry = lookup["AAAA"];
var rand = new Random();
var max = entry.Count();
var ans = entry.Skip(rand.Next(max)).First();

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

var values = new[] {
    new KeyValuePair<string,string> ("AAAA","ACFE"),
    new KeyValuePair<string,string> ("AAAA","AAFE"),
    new KeyValuePair<string,string> ("AAAA","CAED"),
    new KeyValuePair<string,string> ("AAAA","HSGB"),

    new KeyValuePair<string,string> ("AAGB","ZZZZ"),
    new KeyValuePair<string,string> ("AAGB","XXXX"),
    new KeyValuePair<string,string> ("AAGB","CAED"),
    new KeyValuePair<string,string> ("AAGB","HSGB"),

    new KeyValuePair<string,string> ("ABDA","YYYY"),
    new KeyValuePair<string,string> ("ABDA","WWWW"),
    new KeyValuePair<string,string> ("ABDA","CAED"),
    new KeyValuePair<string,string> ("ABDA","HSGB"),
};
//Convert array to IGrouping<string,string>
var group = values.GroupBy(k=>k.Key);

// Retrieve random string from entry "AAAA"
var entry = group.First(k=>k.Key == "AAAA");
var rand = new Random();
var max = entry.Count();
var ans = entry.Skip(rand.Next(max)).First().Value;
1 голос
/ 04 февраля 2020

Вы должны полностью изменить свой подход. dynamic предназначен для обстоятельств, когда вы знаете что-то о форме объекта, с которым вы имеете дело (например, он имеет свойство FooBar или i1), но вы не знаете какой тип будет во время компиляции (может быть, это не типизированный язык, такой как JavaScript или Python).

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

0 голосов
/ 04 февраля 2020

Создание номеров с использованием Base26

    class Program
    {
        static void Main(string[] args)
        {
            Base26 base26 = new Base26();
            for(int i = 0; i < base26.MAX_NUM; i++) 
            {
                Console.WriteLine(base26.ToString());
            }
            Console.ReadLine();
        }
    }
    public class Base26
    {
        public int MAX_NUM = (int)Math.Pow(26, 4);
        int current = 0;

        public override string ToString()
        {
            byte[] base26 = new byte[4];
            base26[3] = (byte)(current % 26);
            base26[2] = (byte)((current / 26) % 26);
            base26[1] = (byte)((current / (26 * 26)) % 26);
            base26[0] = (byte)((current / (26 * 26 * 26)) % 26);
            current++;
            if (current == MAX_NUM) current = 0;

            return string.Join("", base26.Select(x => (char)(((byte)'A') + x)));
        } 
    }
...