Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我想从列表中找到最接近的较大纸张尺寸_C#_Linq - Fatal编程技术网

C# 我想从列表中找到最接近的较大纸张尺寸

C# 我想从列表中找到最接近的较大纸张尺寸,c#,linq,C#,Linq,我想从代码中显示的列表中找到最接近的相等或更大的纸张尺寸 List<PaperSize> paper = new List<PaperSize>(); paper.Add(new PaperSize("B5", 516, 729)); paper.Add(new PaperSize("A5", 420, 595)); paper.Add(new PaperSize("A4", 595, 842)); paper.Add(new PaperSize("B4", 729,

我想从代码中显示的列表中找到最接近的相等或更大的纸张尺寸

List<PaperSize> paper = new List<PaperSize>();

paper.Add(new PaperSize("B5", 516, 729));
paper.Add(new PaperSize("A5", 420, 595));
paper.Add(new PaperSize("A4", 595, 842));
paper.Add(new PaperSize("B4", 729, 1032));
paper.Add(new PaperSize("A4L", 842, 595));
paper.Add(new PaperSize("A3", 1191, 842));
paper.Add(new PaperSize("A2", 1685, 1190));
paper.Add(new PaperSize("A1", 2384, 1685));
paper.Add(new PaperSize("A0", 3371, 2384));

int width = 1189;
int height = 840;

string name = paper.SkipWhile(p => p.PaperWidth < width && p.PaperHeight < 
    height).First().PaperName;

Console.WriteLine("Nearest equal or larger papersize is " + name);
如果我提供宽度1189和高度840,我希望选择纸张A3,但结果是A4。 我怎么还A3

编辑:事实上,列表并不总是以特定的方式排序。正因为如此,@Johnny和@Knoop的建议解决了我的问题。接下来,我忘了将PaperSize及其属性PaperName、PaperWidth和PaperHeight包括在内,但你们都正确地认为我有这个属性。

将您的(&p)更改为| |。如果宽度或高度太小,则要跳过

string name = paper.SkipWhile(p => p.PaperWidth < width || p.PaperHeight < 
    height).First().PaperName;
还值得考虑的是,可能没有足够大的纸张尺寸。如果是这种情况,则将name设置为null

string name = paper
    .FirstOrDefault(p => p.PaperWidth >= width && p.PaperHeight >= height)
    ?.PaperName;
当然,只有当您的纸张尺寸列表严格按面积排序时,这些才起作用,最小的排在第一位。如果不是这样,您可以选择浪费空间最小的纸张尺寸:

int area = width * height;

string name = paper
    .Where(p => p.PaperWidth >= width && p.PaperHeight >= height)
    .OrderBy(p => p.PaperWidth * p.PaperHeight - area)
    .FirstOrDefault()
    ?.PaperName;
将&&更改为| |。如果宽度或高度太小,则要跳过

string name = paper.SkipWhile(p => p.PaperWidth < width || p.PaperHeight < 
    height).First().PaperName;
还值得考虑的是,可能没有足够大的纸张尺寸。如果是这种情况,则将name设置为null

string name = paper
    .FirstOrDefault(p => p.PaperWidth >= width && p.PaperHeight >= height)
    ?.PaperName;
当然,只有当您的纸张尺寸列表严格按面积排序时,这些才起作用,最小的排在第一位。如果不是这样,您可以选择浪费空间最小的纸张尺寸:

int area = width * height;

string name = paper
    .Where(p => p.PaperWidth >= width && p.PaperHeight >= height)
    .OrderBy(p => p.PaperWidth * p.PaperHeight - area)
    .FirstOrDefault()
    ?.PaperName;
尝试此操作,不应提前对纸张列表进行排序:

paper.Where(p => p.PaperWidth  - width >= 0 && p.PaperHeight  - height >= 0)
    .OrderBy(p => p.PaperWidth - width + p.PaperHeight  - height)
    .FirstOrDefault();
尝试此操作,不应提前对纸张列表进行排序:

paper.Where(p => p.PaperWidth  - width >= 0 && p.PaperHeight  - height >= 0)
    .OrderBy(p => p.PaperWidth - width + p.PaperHeight  - height)
    .FirstOrDefault();
要求: 给定宽度和高度,请给我大于此宽度和高度的最小纸张尺寸的名称

这有点棘手

假设宽度和高度分别为100和100。你有两份文件:

纸张尺寸A的宽度为105,高度为2000, 纸张尺寸B的宽度为110,高度为110。 两张纸都足够大。如果你首先看宽度,你会选择A纸,因为它的宽度最小。然而,B纸似乎比A纸小得多

所以首先你必须自己思考:什么时候一张纸比另一张纸小?。您需要一个PaperComparer类来实现IComparer:

在连接LINQ语句时,始终确保只有最后一个语句不返回IEnumerable

注:

此LINQ语句始终有效,即使在空的或未排序的AvailablePersizes集合上也是如此 如果将来您决定以不同的方式定义较小的纸张大小,则LINQ语句不必更改 优化 如果你只想要最小的,那么订购所有尺寸的纸张是相当浪费的。考虑使用最小纸张尺寸< /P> 要求: 给定宽度和高度,请给我大于此宽度和高度的最小纸张尺寸的名称

这有点棘手

假设宽度和高度分别为100和100。你有两份文件:

纸张尺寸A的宽度为105,高度为2000, 纸张尺寸B的宽度为110,高度为110。 两张纸都足够大。如果你首先看宽度,你会选择A纸,因为它的宽度最小。然而,B纸似乎比A纸小得多

所以首先你必须自己思考:什么时候一张纸比另一张纸小?。您需要一个PaperComparer类来实现IComparer:

在连接LINQ语句时,始终确保只有最后一个语句不返回IEnumerable

注:

此LINQ语句始终有效,即使在空的或未排序的AvailablePersizes集合上也是如此 如果将来您决定以不同的方式定义较小的纸张大小,则LINQ语句不必更改 优化 如果你只想要最小的,那么订购所有尺寸的纸张是相当浪费的。考虑使用最小纸张尺寸< /P>
FirstOrDefault?我只是复制了他的代码-我不想引入与解决他的问题无关的编辑。他的代码中没有?PaperName或FirstOrDefault。事实上,他的列表是按大小排序的。我想他已经想到了。等等,事实上这不完全是真的。我将添加一条注释。@croxy但他应该有一个FirstOrDefault以避免NullreferenceExceptionFirstOrDefault?我只是复制了他的代码-我不想引入与解决他的问题无关的编辑。他的代码中没有?.PaperName或FirstOrDefault。事实上,他的列表是按大小排序的。我想他已经想到了。等等,事实上这不完全是真的。我要加一个注释。@croxy,但他应该有一个第一个或第一个默认值,以避免出现空引用例外。这个问题是为了平等或更高,这严格要求更高的论文。因此,p=>p.W>=宽度将是一条可行之路。也可能最好采用FirstOrDefault而不是First。除此之外,这个答案可能就是OP想要的。问题是关于eq
或者更高,这需要更高的论文。因此,p=>p.W>=宽度将是一条可行之路。也可能最好采用FirstOrDefault而不是First。除此之外,这个答案可能是OP正在寻找的。记住在当前的解决方案中,你可能会考虑最近的纸张大小。由于这似乎是用于打印,因此使用OrderBy总未使用像素可能会比建议的OrderBy稍微复杂一些。这实际上可以减少废纸的数量,我认为这是保护树木目标的一部分!!NVM,只是注意到区域添加已经在另一个答案中提到了:在当前的解决方案中要考虑到你可能考虑最近的纸张大小。由于这似乎是用于打印,因此使用OrderBy总未使用像素可能会比建议的OrderBy稍微复杂一些。这实际上可以减少废纸的数量,我认为这是保护树木目标的一部分!!nvm,刚刚注意到另一个答案中已经提到了面积增加:-
var smallestFittingPapersizeName = availablePaperSizes
    .Where(paperSize => paperSize.Width >= width && paperSize.Height >= height)
    .OrderBy(paperSize, PaperSizeComparer.AreaComparer)
    .Select(paperSize => paperSize.Name)
    .FirstOrDefault();
    // instead of OrderBy:
    .Aggregate( (paperSizeX, paperSizeY) =>
       ((PaperSizeComparer.AreaComparer.Compare(paperSizeX, paperSizeY) <= 0) ??
          // paperSizeX smaller or equal; X remains the smallest
          paperSizeX :
          // paperSizeX larger: Y is the new smalles:
          paperSizeY)
public TSource MinOrDefault<TSource> (this IEnumerable<TSource> source,
    IComparer<TSource) comparer)
{
    // TODO: exception if source == null
    if (comparer == null)
       comparer = Comparer<TSource>.Default; // use default comparer

    var enumerator = source.GetEnumerator();
    if (enumerator.MoveNext())
    {   // we have at least one source element:
        var smallest = enumerator.Current;

        // continue with the rest of the input sequence:
        while (enumerator.MoveNext())
        {
            // there is still another item
            if (comparer.CompareTo(smallest, enumerator.Current) > 0)
            {
                 // found a smaller item:
                 smallest = enumerator.Current;
            }
         }
         return smallest;
    }
    else
    {   // input collection empty; return default
        return default(TSource);
    }
}
PaperSize smallestFittingPaperSize = availablePaperSizes
    .Where(paperSize => paperSize.Width >= width && paperSize.Height >= height)
    .Min(PaperSizeComparer.AreaCompaerer);