Как объединить несколько похожих списков в один список с условными обозначениями?C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Как объединить несколько похожих списков в один список с условными обозначениями?

Сообщение Anonymous »

У меня есть функция, которая возвращает один из нескольких похожих списков в зависимости от условия. Код генерируется из исходного Dictionary, содержащего данные. Я не привожу генератор, поскольку его код тривиален.

Код: Выделить всё

List GetList(int version)
{
var list = new List();
if (version == 1)
{
list.Add("A");
list.Add("B");
list.Add("C");
list.Add("D");
list.Add("E");
}
if (version == 2)
{
list.Add("A");
list.Add("B");
list.Add("B2");
list.Add("B3");
list.Add("C");
list.Add("D");
list.Add("E");
}
if (version == 3)
{
list.Add("A");
list.Add("B");
list.Add("B2");
list.Add("B3");
list.Add("D");
list.Add("E");
}
if (version == 11)
{
list.Add("A");
list.Add("B");
list.Add("B2");
list.Add("B3");
list.Add("C");
list.Add("D");
list.Add("E");
}
return list;
}
Итак, существует много кода, содержащего в основном повторяющиеся данные. Выше приведен лишь небольшой отрывок.
Я хочу, чтобы сгенерированный код выглядел следующим образом:

Код: Выделить всё

List GetList2(int version)
{
var list = new List();
list.Add("A");
list.Add("B");
if (version >= 2)
{
list.Add("B2");
list.Add("B3");
}
if (version = 11)
{
list.Add("C");
}
list.Add("D");
list.Add("E");
return list;
}
Поэтому мне нужен алгоритм, который может преобразовать исходную информацию Dictionary в форму, подходящую для создания GetList2.Я полагаю, что сигнатура метода должна быть такой (обратите внимание на использование IEquatable, реальные члены списка реализуют этот интерфейс, я использовал строки в вопросе для ясности):

Код: Выделить всё

public class ListMerger
{
public static List Merge(Dictionary input) where T : IEquatable
{
throw new NotImplementedException();
}
}

public record VersionRange(int? MinVersion, int? MaxVersion);

public record VersionedChunk(List Data, List Versions) where T : IEquatable;
По просьбе я подготовил несколько модульных тестов для метода Merge:

Код: Выделить всё

[TestClass]
public sealed class Test1
{
[TestMethod]
public void WhenNoVersions_ReturnEmptyList()
{
Dictionary input = [];

var output = ListMerger.Merge(input);

Assert.AreEqual(0, output.Count);
}

[TestMethod]
public void WhenSingleVersion_ReturnSingleNonVersionedChunk()
{
Dictionary input = new() { [1] = ["A", "B", "C"] };

var output = ListMerger.Merge(input);

Assert.AreEqual(1, output.Count);
Assert.AreEqual(3, output[0].Data.Count);
Assert.IsTrue(output[0].Data.SequenceEqual(["A", "B", "C"]));
Assert.AreEqual(0, output[0].Versions.Count);
}

[TestMethod]
public void WhenAllVersionsAreSame_ReturnSingleNonVersionedChunk()
{
Dictionary input = new()
{
[1] = ["A", "B", "C"],
[2] = ["A", "B", "C"],
};

var output = ListMerger.Merge(input);

Assert.AreEqual(1, output.Count);
Assert.AreEqual(3, output[0].Data.Count);
Assert.IsTrue(output[0].Data.SequenceEqual(["A", "B", "C"]));
Assert.AreEqual(0, output[0].Versions.Count);
}

[TestMethod]
public void WhenElementIsAdded_ProduceVersionedChunk()
{
Dictionary input = new()
{
[1] = ["A", "B", "C"],
[2] = ["A", "B", "B2", "C"],
};

var output = ListMerger.Merge(input);

Assert.AreEqual(3, output.Count);

Assert.AreEqual(2, output[0].Data.Count);
Assert.IsTrue(output[0].Data.SequenceEqual(["A", "B"]));
Assert.AreEqual(0, output[0].Versions.Count);

Assert.AreEqual(1, output[1].Data.Count);
Assert.IsTrue(output[1].Data.SequenceEqual(["B2"]));
Assert.AreEqual(1, output[1].Versions.Count);
Assert.AreEqual(2, output[1].Versions[0].MinVersion);
Assert.IsNull(output[1].Versions[0].MaxVersion);

Assert.AreEqual(1, output[2].Data.Count);
Assert.IsTrue(output[2].Data.SequenceEqual(["C"]));
Assert.AreEqual(0, output[2].Versions.Count);
}

[TestMethod]
public void WhenElementIsRemoved_ProduceVersionedChunk()
{
Dictionary  input = new()
{
[1] = ["A", "B", "C"],
[2] = ["A", "C"],
};

var output = ListMerger.Merge(input);

Assert.AreEqual(3, output.Count);

Assert.AreEqual(1, output[0].Data.Count);
Assert.IsTrue(output[0].Data.SequenceEqual(["A"]));
Assert.AreEqual(0, output[0].Versions.Count);

Assert.AreEqual(1, output[1].Data.Count);
Assert.IsTrue(output[1].Data.SequenceEqual(["B"]));
Assert.AreEqual(1, output[1].Versions.Count);
Assert.IsNull(output[1].Versions[0].MinVersion);
Assert.AreEqual(1, output[1].Versions[0].MaxVersion);

Assert.AreEqual(1, output[2].Data.Count);
Assert.IsTrue(output[2].Data.SequenceEqual(["C"]));
Assert.AreEqual(0, output[2].Versions.Count);
}

[TestMethod]
public void WhenElementIsRemovedAndAddedAgain_ProduceVersionedChunk()
{
Dictionary input = new()
{
[1] = ["A", "B", "C"],
[2] = ["A", "C"],
[3] = ["A", "B", "C"],
};

var output = ListMerger.Merge(input);

Assert.AreEqual(3, output.Count);

Assert.AreEqual(1, output[0].Data.Count);
Assert.IsTrue(output[0].Data.SequenceEqual(["A"]));
Assert.AreEqual(0, output[0].Versions.Count);

Assert.AreEqual(1, output[1].Data.Count);
Assert.IsTrue(output[1].Data.SequenceEqual(["B"]));
Assert.AreEqual(2, output[1].Versions.Count);
Assert.IsNull(output[1].Versions[0].MinVersion);
Assert.AreEqual(1, output[1].Versions[0].MaxVersion);
Assert.AreEqual(3, output[1].Versions[1].MinVersion);
Assert.IsNull(output[1].Versions[1].MaxVersion);

Assert.AreEqual(1, output[2].Data.Count);
Assert.IsTrue(output[2].Data.SequenceEqual(["C"]));
Assert.AreEqual(0, output[2].Versions.Count);
}

[TestMethod]
public void WhenElementIsAddedAndRemovedAgain_ProduceVersionedChunk()
{
Dictionary input = new()
{
[1] = ["A", "B"],
[2] = ["A", "B", "C"],
[3] = ["A", "B"],
};

var output = ListMerger.Merge(input);

Assert.AreEqual(2, output.Count);

Assert.AreEqual(2, output[0].Data.Count);
Assert.IsTrue(output[0].Data.SequenceEqual(["A", "B"]));
Assert.AreEqual(0, output[0].Versions.Count);

Assert.AreEqual(1, output[1].Data.Count);
Assert.IsTrue(output[1].Data.SequenceEqual(["C"]));
Assert.AreEqual(1, output[1].Versions.Count);
Assert.AreEqual(2, output[1].Versions[0].MinVersion);
Assert.AreEqual(2, output[1].Versions[0].MaxVersion);
}

[TestMethod]
public void WhenElementsAreAddedAndRemoved_ProduceVersionedChunks()
{
Dictionary  input = new()
{
[1] = ["A", "B", "C", "D", "E"],
[2] = ["A", "B", "B2", "B3", "C", "D", "E"],
[3] = ["A", "B", "B2", "B3", "D", "E"],
[11] = ["A", "B", "B2", "B3", "C", "D", "E"],
};

var output = ListMerger.Merge(input);

Assert.AreEqual(4, output.Count);

Assert.AreEqual(2, output[0].Data.Count);
Assert.IsTrue(output[0].Data.SequenceEqual(["A", "B"]));
Assert.AreEqual(0, output[0].Versions.Count);

Assert.AreEqual(2, output[1].Data.Count);
Assert.IsTrue(output[1].Data.SequenceEqual(["B2", "B3"]));
Assert.AreEqual(1, output[1].Versions.Count);
Assert.AreEqual(2, output[1].Versions[0].MinVersion);
Assert.IsNull(output[1].Versions[0].MaxVersion);

Assert.AreEqual(1, output[2].Data.Count);
Assert.IsTrue(output[2].Data.SequenceEqual(["C"]));
Assert.AreEqual(2, output[2].Versions.Count);
Assert.IsNull(output[2].Versions[0].MinVersion);
Assert.AreEqual(2, output[2].Versions[0].MaxVersion);
Assert.AreEqual(11, output[2].Versions[1].MinVersion);
Assert.IsNull(output[2].Versions[1].MaxVersion);

Assert.AreEqual(2, output[3].Data.Count);
Assert.IsTrue(output[3].Data.SequenceEqual(["D", "E"]));
Assert.AreEqual(0, output[3].Versions.Count);
}
}
Ссылки на решения на других языках также приветствуются.

Подробнее здесь: https://stackoverflow.com/questions/793 ... nditionals
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»