var nums = new[]{ 1, 2, 3, 4, 5, 6, 7}; var pairs = /* some linq magic here*/ ; => pairs = { {1, 2}, {3, 4}, {5, 6}, {7, 0} }The elements of pairs should be either two-element lists, or instances of some anonymous class with two fields, something like new {First = 1, Second = 2}.
12 Réponses :
Essayez ceci:
int i = 0; var pairs = nums .Select(n=>{Index = i++, Number=n}) .GroupBy(n=>n.Index/2) .Select(g=>{First:g.First().Number, Second:g.Last().Number});
Vous pouvez faire .Sélectionnez ((N, I) => ...) pour obtenir un compteur automatique
var nums = new float[] { 1, 2, 3, 4, 5, 6, 7 }; var enumerable = Enumerable .Range(0, nums.Length) .Where(i => i % 2 == 0) .Select(i => new { F = nums[i], S = i == nums.Length - 1 ? 0 : nums[i + 1] });
Cela reviendra des paires comme {{1,2}, {2,3}, ...}
@Lasse Cela fonctionne bien car je comprends la question, veuillez donc révoquer votre bowvote
Ceci donne toutes les paires possibles (VB.NET): edit: p> Remarque: la dernière paire est manquante, Travailler sur celui-ci p> Edit: p> Union UniquesPairs code> avec la paire
{nums.Last, 0} code> p> < / p>
Je n'ai pas remarqué que les paires étaient en séquence. J'ai édité la réponse
Cela pourrait être un peu plus général que nécessaire - vous pouvez définir un élément edit: strong> p> Si vous souhaitez ajouter des zéros (ou un autre nombre) au cas où le dernier groupe est d'une taille différente: p> itemsingRoup personnalisé code>:
Cool! Une mise en garde, le dernier élément de paires n'aura qu'un seul élément si la liste des chiffres a un nombre impair. Par exemple. Nums = {1,2,3} => paires = {{1, 2}, {3}}
Voir la mise à jour de l'affaire Général. Si vous n'en avez besoin que de deux éléments par groupe, vous pouvez effectuer une vérification plus simple pour numount nums.count () code> et ajouter un
0 code> si c'est impair.
int[] numbers = new int[] { 1, 2, 3, 4, 5, 6, 7 }; var result = numbers.Zip(numbers.Skip(1).Concat(new int[] { 0 }), (x, y) => new { First = x, Second = y }).Where((item, index) => index % 2 == 0);
J'ajouterai toujours un élément dont la valeur est 0, elle sera automatiquement ignorée si la longueur des nombres est même.
Je ne savais pas qu'il y a une version où () qui prend en charge l'indexation. +1
(AVERTISSEMENT: Ça a l'air laids)
var pairs = x.Where((i, val) => i % 2 == 1) .Zip( x.Where((i, val) => i % 2 == 0), (first, second) => new { First = first, Second = second }) .Concat(x.Count() % 2 == 1 ? new[]{ new { First = x.Last(), Second = default(int) }} : null);
Voler de Danny Chen, vous pouvez ajouter un élément «0» à la 2e argument de ZIP et se débarrasser ainsi de votre dernier bloc .concat (...).
var w = from ei in nums.Select((e, i) => new { e, i }) group ei.e by ei.i / 2 into g select new { f = g.First(), s = g.Skip(1).FirstOrDefault() };
Aucune des méthodes de LINQ par défaut ne peut faire cela paresseusement et avec une seule analyse. Ziper la séquence avec elle-même fait 2 analyses et groupement n'est pas entièrement paresseux. Votre meilleur pari est de le mettre en œuvre directement:
public static IEnumerable<T[]> Partition<T>(this IEnumerable<T> sequence, int partitionSize) { Contract.Requires(sequence != null) Contract.Requires(partitionSize > 0) var buffer = new T[partitionSize]; var n = 0; foreach (var item in sequence) { buffer[n] = item; n += 1; if (n == partitionSize) { yield return buffer; buffer = new T[partitionSize]; n = 0; } } //partial leftovers if (n > 0) yield return buffer; }
En regardant toutes les réponses, il semble que Linq n'est pas la meilleure approche ici. Votre implémentation est assez propre.
Il devrait être statique publique iEnumerable
var pairs = nums.InSetsOf(2, true, 0).ToArray();
IList<int> numbers = new List<int> {1, 2, 3, 4, 5, 6, 7}; var batched = numbers.Batch(2);
Une autre option consiste à utiliser la méthode SelectMany Linq. C'est plus pour ceux qui souhaitent itérer une liste d'articles et pour chaque article de retour 2 ou plus de ses propriétés. Pas besoin de boucler à nouveau sur la liste pour chaque propriété, juste une fois.
Merci pour la réponse, mais cela reçoit des propriétés de chaque élément et les aplatit dans une liste unique. Ce n'est pas la question de la question initiale.
Une autre solution simple utilisant dernier élément n'est pas valide et doit être supprimé avec index code> et
index + 1 code>.
Skilastn () Code>. P> P>
Duplicata exact de la question posée par vous-même Stackoverflow.com/Questtions/3575925/...
@Jani non, ce n'est pas. Cela demande un équivalent à la méthode zip de Python (ou Ruby) -> prend deux listes et constitue une liste de tuples. Cette question concerne partitionnement d'une liste unique.
Une réponse très similaire - pour la fenêtre coulissante pour obtenir
{{1,2}, {2,3}, {3,4}, {3,4} ... code> - qui devrait être facile à adapter est ici: Stackoverflow .Com / Questions / 577590 / ...
@Jani en fait, j'avais tort aussi, cette question ne concerne pas la méthode zip (), mais toujours, c'est une question différente.
@Richard qui utilise un itérateur personnalisé, pas une expression LINQ. J'admets que cela pourrait être le moyen le plus propre d'y aller.
@Cristi, enfin je monte avec la solution :-)