J'ai une liste de chaînes que j'envoie à une file d'attente. J'ai besoin de scinder la liste afin que je finisse par une liste de listes où chaque liste contient un nombre maximum (défini par l'utilisateur) de chaînes. Donc, par exemple, si j'ai une liste avec les suivants A, B, C, D, E, F, G, H, I et la taille maximale d'une liste sont 4, je veux retrouver une liste de listes où Le premier élément de liste contient: A, B, C, D, la deuxième liste: E, F, G, H et le dernier élément de la liste Il suffit de: I. J'ai regardé la fonction "Maintien", mais je ne suis pas sûr si C'est la meilleure approche. Toute solution pour cela? P>
3 Réponses :
Vous pouvez configurer une liste Ignorer code> et prendre code> pour diviser la liste: IEnumerable<string> allStrings = new[] { "A", "B", "C", "D", "E", "F", "G", "H", "I" };
List<IEnumerable<string>> listOfLists = new List<IEnumerable<string>>();
for (int i = 0; i < allStrings.Count(); i += 4)
{
listOfLists.Add(allStrings.Skip(i).Take(4));
}
J'ai voté pour cela comme c'est juste ce dont j'avais besoin. RPM1984 a également donné une bonne réponse, mais celui-ci ajusté directement dans mon code.
Et si j'ai besoin de scinder la liste sur 5 listes, peu importe le nombre de cordes de ces listes finir?
/// <summary>
/// Splits a <see cref="List{T}"/> into multiple chunks.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list">The list to be chunked.</param>
/// <param name="chunkSize">The size of each chunk.</param>
/// <returns>A list of chunks.</returns>
public static List<List<T>> SplitIntoChunks<T>(List<T> list, int chunkSize)
{
if (chunkSize <= 0)
{
throw new ArgumentException("chunkSize must be greater than 0.");
}
List<List<T>> retVal = new List<List<T>>();
int index = 0;
while (index < list.Count)
{
int count = list.Count - index > chunkSize ? chunkSize : list.Count - index;
retVal.Add(list.GetRange(index, count));
index += chunkSize;
}
return retVal;
}
Reference: http://www.chinhdo.com/20080515/chunking/
Votre méthode est bien super! C'est ce que je voulais exactement.
Certaines lecture associée:
Sinon, variation mineure sur réponse acceptée pour travailler avec Enumerables (pour le chargement et le traitement des paresseux, au cas où la liste est grosse / chère). Je noterais que matérialisant chaque morceau / segment (par exemple via .tolist code> ou .toRayray CODE> ou simplement énumérer chaque morceau) pourrait avoir des tests - voir les tests. P> Méthodes H2>
void Main()
{
var length = 10;
var size = 4;
test(10, 4);
test(10, 6);
test(10, 2);
test(10, 1);
var sideeffects = Enumerable.Range(1, 10).Select(i => {
string.Format("Side effect on {0}", i).Dump();
return i;
});
"--------------".Dump("Before Chunking");
var result = Chunk(sideeffects, 4);
"--------------".Dump("After Chunking");
result.Dump("SideEffects");
var list = new List<int>();
foreach(var segment in result) {
list.AddRange(segment);
}
list.Dump("After crawling");
var segment3 = result.Last().ToList();
segment3.Dump("Last Segment");
}
// test
void test(int length, int size) {
var list = Enumerable.Range(1, length);
var c1 = Chunk(list, size);
c1.Dump(string.Format("Results for [{0} into {1}]", length, size));
Assert.AreEqual( (int) Math.Ceiling( (double)length / (double)size), c1.Count(), "Unexpected number of chunks");
Assert.IsTrue(c1.All(c => c.Count() <= size), "Unexpected size of chunks");
}
La meilleure solution que j'ai trouvée est de Morelinq - . google.com/p/morelinq/source/browse/morelinq/batch.cs