C# 在一个列表';s的上限和下限
我现在用下面的方法计算税率C# 在一个列表';s的上限和下限,c#,linq,C#,Linq,我现在用下面的方法计算税率 int testValue = 180000; List<TaxBracket> taxes = new List<TaxBracket>(); taxes.Add(new TaxBracket(18199, 0)); //0 to 18199 taxes.Add(new TaxBracket(36999, 19)); //18200 to 36999 taxes.Add(new TaxBracket(79999, Convert.ToDec
int testValue = 180000;
List<TaxBracket> taxes = new List<TaxBracket>();
taxes.Add(new TaxBracket(18199, 0)); //0 to 18199
taxes.Add(new TaxBracket(36999, 19)); //18200 to 36999
taxes.Add(new TaxBracket(79999, Convert.ToDecimal(32.50D))); //37000 to 79999
taxes.Add(new TaxBracket(179999, 37)); //80000 to 179999
taxes.Add(new TaxBracket(180000, 47)); //180000
decimal result = taxes[taxes.Count-1].Value;
for (int i = 0; i < taxes.Count; i++)
{
if (i == 0)
{
if (testValue < taxes[i].Limit)
result = 0;
}
if (i > 0)
{
if (testValue < taxes[i].Limit && testValue > taxes[i - 1].Limit)
{
result = taxes[i].Value;
}
}
}
Console.WriteLine(result);
int testValue=180000;
列表税=新列表();
增列(新税级(18199,0))//0至18199
增列(新税级(36999,19))//18200至36999
增税(新税级(79999,转换为具体税率(32.50D))//37000至79999
增列(新税级(179999,37))//80000至179999
增列(新税级(180000,47))//180000
十进制结果=税[taxes.Count-1]。值;
for(int i=0;i0)
{
if(testValuetaxes[i-1]。限制)
{
结果=税收[i]。价值;
}
}
}
控制台写入线(结果);
LINQ中是否有其他替代方案可以这样做,而不是使用这种老式方法?看起来很接近,但有点不同。如果我理解正确,这就是您想要的:
var result = taxes.OrderBy(item => item.Limit)
.SkipWhile(item => item.Limit < testValue)
.FirstOrDefault()?.Value;
这种方法从不同的方向来看待问题。仅取等于或等于testValue
的项目,然后对其进行排序,并取第一个项目。作为Linq替代方案,我建议使用二进制搜索,前提是税务
已排序:
int index = taxes.BinarySearch(
new TaxBracket(testValue, -1), // -1: this parameter is ignored
Comparer<TaxBracket>.Create((left, right) => left.Limit.CompareTo(right.Limit)));
if (index < 0)
index = ~index - 1; // in between of two indexes
var result = taxes[index].Value;
int index=taxes.BinarySearch(
新的TaxBracket(testValue,-1),/-1:忽略此参数
创建((左,右)=>left.Limit.CompareTo(right.Limit));
如果(指数<0)
索引=~索引-1;//在两个索引之间
var结果=税收[指数]。价值;
当您使用长列表时,二进制搜索非常有用(当Linq提供
O(N)
one时,该算法确保O(log(N))
复杂性);但是当税很小时,LinqSkipWhile
(参见吉拉德·格林的回答)更具可读性你能告诉我逻辑:如何税括号(36999,19))
将从18200到36999
,18200
来自何处?@un lucky-该系列中的每件物品都是该系列中的顶级数字。因此,项0表示所有值,直到达到限制-即18199尝试以下解决方案,如果值大于表中的值,则该解决方案将返回null:decimal?结果=税。其中(x=>testValuex.Value)。LastOrDefault();与@Gilad Green建议的方法相比,这是否更好?@3615-我想说,在较小的系列上,性能并不重要,但在较大的系列上,这更有效:)@Dmitry-不错approach@3615:处理长列表时,二进制搜索更好(时间复杂度更好-O(log(N))
v.O(N)
);这是Linq的一个土著(正如问题中所说的)。主要缺点是可读性差。感谢您的澄清!
int index = taxes.BinarySearch(
new TaxBracket(testValue, -1), // -1: this parameter is ignored
Comparer<TaxBracket>.Create((left, right) => left.Limit.CompareTo(right.Limit)));
if (index < 0)
index = ~index - 1; // in between of two indexes
var result = taxes[index].Value;