У меня есть цепочка из пяти предметов. Каждый объект имеет состояние, которое может быть истинным или ложным. Мне нужно создать коллекцию или словарь всех возможных цепочек, в зависимости от состояния объекта индивидуально. Например :
Value Key
obj1 obj2 obj3 obj4 obj5 00000 //obj1=false obj2=false obj3=false obj4=false obj5=false
obj1 obj2 obj3 obj4 obj5 00001 //obj1=false obj2=false obj3=false obj4=false obj5=true
obj1 obj2 obj3 obj4 obj5 .....
obj1 obj2 obj3 obj4 obj5 11111 //obj1=true obj2=true obj3=true obj4=true obj5=true
Как это сделать правильно и элегантно?
скажем, каждый объект имеет тип
class Unit
{
public bool State {get;set;}
}
цепочка
class Chain
{
public Unit obj1 {get;set;}
public Unit obj2 {get;set;}
public Unit obj3 {get;set;}
public Unit obj4 {get;set;}
public Unit obj5 {get;set;}
}
Элемент словаря должен быть: Цепочка как значение и 10101 как ключ.
@Groo спасибо, а как наполнить и создать базу коллекции на этой информации?
@ Z.R.T .: что такое цепочка объектов? Что представляют собой эти предметы? Вы про bool
? Отложите на мгновение реализацию и попытайтесь объяснить, что именно вы пытаетесь сделать.
что такое цепочка из 5 предметов?
Что будет внутри этой коллекции или словаря? Ценности bool
? Они вам не нужны, просто используйте byte
для хранения состояния (enum
- лучший выбор, если вы хотите дать имя отдельному объекту и получить доступ к его значению по этому имени, где значение равно true
для 1
и false
для 0
).
Попробуйте использовать Linq: мы хотим, чтобы Range
из 0..31
материализовался как Dictionary
. Единственная (возможная) проблема - это манипуляции с битами:
2**n
(в нашем случае 2**5 == 32
) для диапазон, мы можем сдвинуть 1
в положениях n
влево, в нашем случае: 1 << 5 == 0b10000 == 32
k
, мы можем использовать value >> k & 1 != 0
:Небольшая картина того, что происходит
011...0101...1 : value
^
k-th bit
После переключения правильно (value >> k
):
011...01
^
former k-th bit is now the 1st one (`01...1` part's gone)
011...01 after bitwise & 1
1
--------
1 either 1 or 0 (depending on if k-th bit set or not)
Код:
using System.Linq;
...
var demo = Enumerable
.Range(0, 1 << 5)
.ToDictionary(key => key,
key => new {
//TODO: put right object here instead the anonymous one
obj1 = (key >> 4 & 1) != 0,
obj2 = (key >> 3 & 1) != 0,
obj3 = (key >> 2 & 1) != 0,
obj4 = (key >> 1 & 1) != 0,
obj5 = (key >> 0 & 1) != 0,
});
Console.Write(string.Join(Environment.NewLine, demo));
Исход:
[0, { obj1 = False, obj2 = False, obj3 = False, obj4 = False, obj5 = False }]
[1, { obj1 = False, obj2 = False, obj3 = False, obj4 = False, obj5 = True }]
[2, { obj1 = False, obj2 = False, obj3 = False, obj4 = True, obj5 = False }]
...
[29, { obj1 = True, obj2 = True, obj3 = True, obj4 = False, obj5 = True }]
[30, { obj1 = True, obj2 = True, obj3 = True, obj4 = True, obj5 = False }]
[31, { obj1 = True, obj2 = True, obj3 = True, obj4 = True, obj5 = True }]
Для полноты картины попробуйте объяснить логику манипуляции с битами.
@ Кунал Мукерджи: Спасибо! Побитовая логика вполне может нуждаться в объяснениях. Я отредактировал ответ
Допустим, 00000 = 0 и 11111 = 31 как двоичные данные
List<string> result = new List<string>();
for(int i=0;i<32;i++)
{
result.Add(Convert.ToString(i, 2).PadLeft('5','0'));
}
Вероятно, было бы разумнее вести список единиц вместо того, чтобы иметь отдельное свойство для каждого элемента, т.е.
class Chain
{
readonly List<Unit> _units;
public IReadOnlyList<Unit> Units => _units;
public string Key => string.Concat(_units.Select(u => u.State ? "1" : "0"));
public Chain(params bool[] units)
{
_units = units.Select(u => new Unit { State = u }).ToList();
}
}
Тогда, если вы создадите «цепочку»:
var chain = new Chain(true, false, false, true, false);
вы получите его ключ с помощью chain.Key
.
Ваш ключ напоминает двоичную интерпретацию чисел между
0
и31
. Но я вообще-то не понимаю, что такое «цепочка объектов».