Wie füge ich mehrere ähnliche Listen mit Bedingungen zu einer einzigen Liste zusammen?C#

Ein Treffpunkt für C#-Programmierer
Guest
 Wie füge ich mehrere ähnliche Listen mit Bedingungen zu einer einzigen Liste zusammen?

Post by Guest »

Ich habe eine Funktion, die basierend auf der Bedingung eine von mehreren ähnlichen Listen zurückgibt. Der Code wird aus der Quelle Dictionary generiert, die die Daten enthält. Ich stelle den Generator nicht zur Verfügung, da sein Code trivial ist.

Code: Select all

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;
}
Es gibt also viel Code, der größtenteils doppelte Daten enthält. Oben ist nur ein kurzer Auszug.
Ich möchte, dass der generierte Code stattdessen so aussieht:

Code: Select all

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;
}
Ich brauche also einen Algorithmus, der die Quell-Dictionary-Informationen in eine Form umwandeln kann, die zum Generieren von GetList2 geeignet ist.Ich nehme an, dass die Methodensignatur so aussehen sollte (beachten Sie die Verwendung von IEquatable, die echten Listenmitglieder implementieren diese Schnittstelle, ich habe der Klarheit halber in der Frage Zeichenfolgen verwendet):

Code: Select all

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;
Auf Wunsch habe ich einige Unit-Tests für die Merge-Methode vorbereitet:

Code: Select all

[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);
}
}
Links zu Lösungen in anderen Sprachen sind ebenfalls willkommen.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post