所以我有一个项目清单。列表中的每个项目都有一个名为notional
的属性。现在,列表已经排序。我需要做的是,开发一个将列表类型设置为以下之一的函数:
notional
对于每个项目都是相同的notional
在整个计划过程中减少(可能在元素之间保持不变但它永远不会上升,并且应该结束)notional
在整个计划过程中增加(可能在元素之间保持不变但它应该永远不会下降,并且应该结束更高)notional
上升和下降(可以结束相同,更高或更低,但不应该对每个元素都相同,不应该像其他类型一样分类)这种方法看起来会是什么样的,以及通过列表找出问题的最有效方法是什么?
谢谢!
答案 0 :(得分:1)
这将是一种直接的方式:
bool hasGoneUp = false;
bool hasGoneDown = false;
T previous = null; // T is the type of objects in the list; assuming ref type
foreach(var item in list)
{
if (previous == null) {
previous = item;
continue;
}
hasGoneUp = hasGoneUp || item.notional > previous.notional;
hasGoneDown = hasGoneDown || item.notional < previous.notional;
if(hasGoneUp && hasGoneDown) {
return Trend.Rollercoaster;
}
previous = item;
}
if (!hasGoneUp && !hasGoneDown) {
return Trend.Bullet;
}
// Exactly one of hasGoneUp and hasGoneDown is true by this point
return hasGoneUp ? Trend.Accreting : Trend.Amortizing;
答案 1 :(得分:1)
从第一项循环到最后一项
2.1。如果以前是名义上的&lt;下一个概念
2.1.a. If trendOut = Amortizing return RollerCoaster
2.1.b. Else set trendOut = Accreting
2.2。如果以前的名义&gt;下一个概念
2.2.a. If trendOut = Accreting return RollerCoaster
2.2.b. Else set trendOut = Amortizing
答案 2 :(得分:0)
你可以做一些像这个简单的事情
var changeList = new List<Integer>
for(i = 0; i < yourList.Count() - 1; i++)
{
changeList.Add(yourList.Item(i + 1) - yourList.Item(i));
}
//Determine if the nature of the list
var positiveChangeCount = changeList.Where(x => x < 0);
var negativeChangeCount = changeList.Where(x => X > 0);
if (positiveChangeCount = yourList.Count)
{
Accreting;
}
elseif (negativeChangeCount = yourList.Count)
{
Amortizing;
}
elseif (negativeChangeCount + PositiveChangeCount = 0)
{
Bullet;
}
else
{
Rollercoaster;
}
答案 3 :(得分:0)
我通常首先通过优化简化然后再进行性能优化。因此,我首先制作第二个N-1元素列表,其{元素}是第一个列表的{notionals}之间的差异。
因此,对于第二个列表,我希望以下列出您的需求
你可以在一次通过中优化它。基本上,这是对数据的独立区分。
答案 4 :(得分:0)
bool OnlyGreaterOrEqual=true;
bool OnlyLessOrEqual=true;
foreach(int i=1;i<itemList.Count;i++){
if(itemList[i].notional>itemList[i-1].notional){
OnlyLessOrEqual=false;
}else if(itemList[i].notional<itemList[i-1].notional){
OnlyGreaterOrEqual=false;
}
}
if(OnlyGreaterOrEqual && OnlyLessOrEqual){
return "Bullet";
}else if(OnlyGreaterOrEqual){
return "Accreting":
}else if(OnlyLessOrEqual){
return "Amortizing";
}else{
return "RollerCoast";
}
答案 5 :(得分:0)
这基本上是Linq对丹麦语答案的实现。它需要(最坏的情况)3次通过列表,但因为它们非常小,从性能的角度来看并不重要。 (我将其编写为int
列表,因此您必须轻松修改它才能使用您的类型。
var tmp = values
.Skip(1)
.Zip( values, (first, second) => first - second )
.ToList();
var up = tmp.Any( t => t > 0 );
var down = tmp.Any( t => t < 0 );
if( up && down )
// Rollercoaster
else if( up )
// Accreting
else if( down )
// Amortizing
else
// Bullet
您还可以(ab)使用Aggregate
运算符和Tuple
作为一个查询来执行此操作。但是,如果集合为空并且在生产代码中使用有点奇怪,则会失败。
var result = values.Skip(1).Aggregate(
Tuple.Create<int, bool, bool>( values.First(), false, false ),
( last, current ) => {
return Tuple.Create(
current,
last.Item2 || (current - last.Item1) > 0,
last.Item3 || (current - last.Item1) < 0 );
});
result
将是包含以下内容的元组:
Item2
将包含一个布尔值,指示是否有任何元素大于前一个元素Item3
将包含一个布尔值,指示是否有任何元素小于前一个元素可以使用与上面相同的switch语句来确定数据遵循的模式。