LINQ标量操作

本文关键字:操作 标量 LINQ | 更新日期: 2023-09-27 18:09:12

出于好奇。有人能想出一种方法来集成剩下的两行代码与LINQ操作吗?

var code = string.Format("{0:00000}{1:000000000}{2:0000000}", SelectedPreset.Prefix, i, SelectedPreset.Amount);
// calculate checksum
var checksum = code
    .Reverse()
    .Select((c, index) => new { IsOdd = (index & 1) == 1, Value = (int) Char.GetNumericValue(c) })
    .Select(x => x.IsOdd ? x.Value : x.Value*3)
    .Aggregate((a, b) => a + b);
var rounded = ((checksum + 10 - 1)/10)*10;
checksum = rounded - checksum;

LINQ标量操作

不要。代码已经很清楚了。为什么你想要跳过一些障碍,最终得到一些可读性较差的东西呢?

重命名checksum。比如(你可以想个更好的名字;关键是不要调用第一个计算(checksum,如果它实际上不是校验和):

var intermediate = // your LINQ expression
var rounded = ((intermediate + 10 -1) / 10) * 10;
var checksum = rounded - intermediate;

也改变

IsOdd = (index & 1) == 1

IsIndexOdd = index % 2 != 0

如果你真的想知道:

 var checksum =
     new [] {
         code
            .Reverse()
            .Select((c, index) => new {
                IsIndexOdd = index % 2 != 0,
                Value = (int) Char.GetNumericValue(c)
            })
            .Select(x => x.IsIndexOdd ? x.Value : 3 * x.Value)
            .Aggregate((a, b) => a + b)
     }
     .Select(x => new { Rounded = ((x + 10 - 1) / 10) * 10, Intermediate = x })
     .Select(x => x.Rounded - x.Intermediate)
     .Single();

不要这样做

您可以通过定义自己的扩展方法来做到这一点,技术上不是linq,但有点。就像Jason说的,不要这样做。

public static class CrazyExtension
{
    public S Project<T,S>(this T value, Func<T,S> Selector)
    {
        return Selector(value);
    }
}

这允许你使用:

 var checksum =
         code
         .Reverse()
         .Select((c, index) => new { IsOdd = (index & 1) == 1, Value = (int) Char.GetNumericValue(c) })
         .Select(x => x.IsOdd ? x.Value : x.Value*3)
         .Aggregate((a, b) => a + b)
         .Project(x => new { Rounded = ((x + 10 - 1) / 10) * 10, Intermediate = x })
         .Project(x => x.Rounded - x.Intermediate);

Replace

.Aggregate((a, b) => a + b); 

.Aggregate(0, (a, b) => a + b, x => ((x + 10 - 1) / 10) * 10 - x);