Question

J'ai une collection de chaînes C #. Chaque chaîne est une phrase pouvant apparaître sur une page. J'ai aussi une collection de sauts de page qui est une collection d'int. représentant l'index où la collection de chaînes est fractionnée sur une nouvelle page.

Exemple: chaque groupe de 10 éléments de la collection de chaînes est une page. Par conséquent, la collection de sauts de page est une collection d'entiers avec les valeurs 10, 20, 30. ...

Donc, s'il y a 2 pages de chaînes, il y aura 1 élément dans la collection de sauts de page et s'il y a 1 page, la collection de sauts de page n'aura aucun élément.

J'essaie de créer la fonction suivante:

List<string> GetPage(List<string> docList, List<int> pageBreakList, int pageNum)
{
    // This function returns a subset of docList - just the page requested
}

J'ai écrit quelques mots sur cette fonction et continue de mettre au point des instructions complexes if et switch pour prendre en compte les documents d'une ou deux pages et les numéros de page demandés en dehors de la plage (par exemple, la dernière page doit être renvoyée si le numéro de page est supérieur au nombre de pages et à la première page si le numéro de page est égal ou inférieur à 0).

Mon problème avec ce problème me conduit à poser la question suivante: existe-t-il un modèle ou un algorithme bien connu pour traiter ce type de requête de sous-ensemble?

Était-ce utile?

La solution

" Pure " Linq ne convient pas à ce problème. La meilleure solution consiste à utiliser les méthodes et les propriétés de List (T). Il n'y a pas beaucoup de cas particuliers.

//pageNum is zero-based.
List<string> GetPage(List<string> docList, List<int> pageBreaks, int pageNum)
{

  // 0 page case
  if (pageBreaks.Count != 0)
  {
    return docList;
  }

  int lastPage = pageBreaks.Count;

  //requestedPage is after the lastPage case
  if (requestedPage > lastPage)
  {
    requestedPage = lastPage;
  }


  int firstLine = requestedPage == 0 ? 0  :
      pageBreaks[requestedPage-1];
  int lastLine = requestedPage == lastPage ? docList.Count :
      pageBreaks[requestedPage];

  //lastLine is excluded.  6 - 3 = 3 - 3, 4, 5

  int howManyLines = lastLine - firstLine;

  return docList.GetRange(firstLine, howManyLines);
}

Vous ne souhaitez pas remplacer la propriété .Count par la méthode .Count () de linq. Vous ne souhaitez pas remplacer la méthode .GetRange () par les méthodes .Skip (n) .Take (m) de linq.

Linq conviendrait mieux si vous souhaitez projeter ces collections dans d’autres collections:

IEnumerable<Page> pages =
  Enumerable.Repeat(0, 1)
  .Concat(pageBreaks)
  .Select
  (
    (p, i) => new Page()
    {
      PageNumber = i,
      Lines = 
        docList.GetRange(p, ((i != pageBreaks.Count) ? pageBreaks[i] : docList.Count)  - p)
    }
  );

Autres conseils

Je ne sais pas à quoi sert la liste des sauts de page. Je penserais de cette façon. Une collection de chaînes, un numéro de page et la taille de la page. Ensuite, vous pourriez faire quelque chose comme:

List<string> strings = ...
int pageNum = ...
int pageSze = ...

if (pageNum < 1) pageNum = 1;
if (pageSize < 1) pageSize = 1;

List<string> pageOfStrings = strings.Skip( pageSize*(pageNum-1) ).Take( pageSize ).ToList();

Si le nombre de pages varie d’une page à l’autre en fonction de votre commentaire, essayez l'une des solutions ci-dessous. Vous devrez peut-être ajuster la vérification des conditions de bord ...

List<string> strings = ...
List<int> sizes = ...

int pageNum = ...
int itemsToSkip =  0;
int itemsToTake = 1;

if (pageNum > 1)
{
   sizes.Take( pageNum - 2).Sum();

   if (pageNum <= sizes.Count)
   {
       itemsToTake = sizes[pageNum-1]
   }
{

List<string> pageOfStrings = strings.Skip( itemsToSkip ).Take( itemsToTake );
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top