linq 将数组切割成不同大小的子数组(C#)

w8f9ii69  于 2022-12-06  发布在  C#
关注(0)|答案(2)|浏览(140)

在做编码卡塔时,我遇到了一个轻微的逻辑问题,我无法找到解决方案。这不是完成任务的硬性要求,但它让我好奇如何处理它。
Kata通过一组定价规则模拟应用定价折扣和超市结账(see full Kata here)。为了使用一些继承和接口功能,我添加了一个“Buy X,get Y free”规则。当所讨论的Y1时,它工作得很好,但在那之后就开始变得有点模糊了...
例如,我尝试了“购买3,免费获得2”的想法,我尝试将商品分成5组,然后通过减去其中两种商品的价格来计算每组的折扣:

public override double CalculateDiscount(Item[] items)
    {
        //per the example described above
        //_groupSize = 5, _buy = 3
        //meaning 2 out of every group of 5 items should be free

        var discountGroups = new List<IEnumerable<Item>>();

        for (var i = 0; i < items.Length / _groupSize; i++)
        {
            discountGroups.Add(items.Skip(i * _groupSize).Take(_groupSize));
        }

        return discountGroups
            .Sum(group => group
                .Skip(_buy)
                .Sum(item => item.Price)
            );
    }

我发现上面的代码按预期工作(如果每个项的Price属性都是1.00,上面的代码将返回2.00)。(因此,您广告中每件商品的价格将为1.002.003.004.003.00)。
我最理想的是,一旦你收藏了三件物品,接下来的两件物品是免费的,无论你选择只拿走其中的一件还是两件,都不会影响价格。我知道这对这个领域来说并不现实,但我有兴趣把它作为一个技术问题来解决。
我有过一些尝试,但还没有成功地接近上面的代码。我认为我需要做的是将数组分组为所需的最小数量的购买物品,然后是可变数量的免费物品。我可能可以硬编码解决这个问题一次,但如果我模拟购买3件物品和获得2件免费物品,这会变得复杂。然后买了3件东西却只拿了一件免费的。
任何关于如何去做这件事的建议都会非常感激!
谢谢,马克

evrscar2

evrscar21#

您的折扣计算有一些错误,例如,如果项目计数小于groupSize,则不创建组。因此,请将i <更改为i <=

for (var i = 0; i <= items.Length / groupSize; i++)
{
    discountGroups.Add(items.Skip(i * groupSize).Take(groupSize));
}

也许这已经是全部了。

ht4b089n

ht4b089n2#

我只想补充一点,扩展方法.Chunk()被添加到了.NET 6中的 System.Linq 命名空间中,它所做的与创建discountGroups所做的完全相同;它将源集合拆分为IEnumerable个具有所请求块大小的块
来源:{1,2,3,4,5,6,7,8}

var chunks = source.Chunk(3);

数据块:{{ 1,2,3 },{ 4,5,6 },{ 7,8 }}
如果可枚举源中的项计数不能被所需的块大小整除,则最后一个块将仅由剩余项组成(即,最后一个块的大小可能小于其他块)。
因此,通过使用.Chunk(),您可以替换以下内容:

var discountGroups = new List<IEnumerable<Item>>();

for (...)
{
    discountGroups.Add(items.Skip(i * _groupSize).Take(_groupSize));
}

与此:

var discountGroups = items.Chunk(_groupSize).ToList();

相关问题