2016-07-13 1 views
2

avoir une telle classe:Comment valider une liste de plages entre elles?

public class MyRange 
{ 
    public int From {get; set;} 
    public int To {get; set;} 

    public MyRange(int from, int to) 
    { 
     From = from; 
     To = to; 
    } 
} 

et ayant une List<MyRange> avec les valeurs suivantes:

var list = new List<MyRange>(); 
list.Add(new MyRange(1, 1000)); 
list.Add(new MyRange(1001, 2000)); 
list.Add(new MyRange(50, 1500)); 
list.Add(new MyRange(1900, 2900)); 

Est-il possible d'avoir une règle FluentValidation qui vérifie que les plages ci-dessus ne se chevauchent pas? (Les écarts entre les gammes sont valables)

Répondre

4

Vous pouvez le faire en ordonnant des plages sur la propriété From, puis vérifier que la propriété To de l'élément avant est inférieure à la propriété From de l'élément courant:

var ordered = list.OrderBy(r => r.From).ToList(); 
var isValid = ordered 
    .Zip(ordered.Skip(1), (a, b) => new {Prior = a, Current = b}) 
    .All(p => p.Prior.To <= p.Current.From); 
0

LINQ peut vous aider ici:

bool overlaps = list.Any(r => list 
          .Except(new[] { r }) 
          .Any(r2 => r.From >= r2.From && r.To <= r2.To) 
         ); 
0

En utilisant imbriqué .Any:

list.Any(x => list.Any(y => x.From < y.From && x.To > y.From || x.From < y.From && x.To > y.From)) 

Cette Itère la liste en deux foreach instructions une avec la variable x et une avec la variable y et les contrôles de chevauchement entre chacune de ces variables en utilisant la condition qui aurait été utilisé dans les deux foreach instructions:

x.From < y.From && x.To > y.From || x.From < y.From && x.To > y.From 

L'avantage est que ceci est plus clair que d'itérer les deux listes et d'appliquer la condition, et il peut être écrit sur une seule ligne sans aucun effort.