خوارزمية / نمط لاختيار مجموعات فرعية باستخدام LINQ وC #

StackOverflow https://stackoverflow.com/questions/238340

سؤال

ولدي C # مجموعة من السلاسل. كل سلسلة هي الجملة التي يمكن أن تظهر على صفحة. ولدي أيضا مجموعة من فواصل الصفحات التي هي عبارة عن مجموعة من إدارة النزاهة المؤسسية. يمثل مؤشر حيث يتم تقسيم مجموعة من السلاسل إلى صفحة جديدة.

مثال: كل 10 العناصر الموجودة في المجموعة السلسلة صفحة حتى جمع فواصل الصفحات سيكون عبارة عن مجموعة من لكثافة مع قيم 10، 20، 30. ...

وحتى إذا كان هناك 2 صفحات من السلاسل ثم سيكون هناك 1 عنصر في مجموعة فاصل صفحات وإذا كان هناك 1 الصفحة ثم فإن جمع فاصل صفحات يكون الصفر البنود.

وأنا أحاول أن إنشاء الدالة التالية:

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

ولقد اتخذت بضعة طعنات في كتابة هذه الوظيفة والحفاظ على الخروج مع مجمع إذا والتبديل البيانات إلى أن تأخذ في حساب واحد وثيقتين الصفحة وأرقام الصفحات المطلوبة خارج النطاق (على سبيل المثال الصفحة الأخيرة ينبغي أن تعاد إذا رقم الصفحة أكبر من عدد الصفحات والصفحة الأولى إذا كان رقم الصفحة هو 0 أو أقل).

وبلدي الصراع مع هذه المشكلة يقودني إلى طرح السؤال التالي: هل هناك نمط معروفة أو الخوارزمية لمعالجة هذا النوع من الاستعلام فرعية

هل كانت مفيدة؟

المحلول

و"الأبيض" ينق ليس مناسبا لهذه المشكلة. الأنسب هو الاعتماد على أساليب وخصائص من قائمة (T). ليست هناك -that- العديد من الحالات الخاصة.

//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);
}

وأنت لا تريد أن تحل محل الملكية .Count مع طريقة LINQ في .Count (). كنت لا تريد استبدال الأسلوب مع .Skip (ن) .Take (م) طرق LINQ في .GetRange ().

وينق سيكون أفضل مناسبا إذا أردت إبراز هذه المجموعات إلى مجموعات أخرى:

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)
    }
  );

نصائح أخرى

ولست متأكدا ما قائمة فواصل الصفحة هي ل. وأود أن أعتقد أنه من هذا الطريق. مجموعة من السلاسل، ورقم الصفحة، وحجم الصفحة. ثم هل يمكن أن تفعل شيئا مثل:

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();

في حالة حيث تختلف عدد الصفحات لكل صفحة كما في تعليقك، حاول شيئا مثل أدناه. قد تحتاج إلى ضبط فحص حالة حافة ...

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 );
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top