循环遍历数组并在新数组中保存x个观察值

时间:2015-02-20 09:23:00

标签: c# .net for-loop

我正在尝试遍历数组和i。我需要前10个值的MAX值。

所以if i= 20,我需要math.max i-10, i-9, i-8...等等。但我正在努力让这个工作。

static public void TA(DateTime[] datePrice, double[] openPrice, double[] highPrice, double[] lowPrice, double[] closePrice)
{
    #region declare variables
    int outBegIdx;
    int outNbElement;
    int SmaPeriod = 20;
    int TOTAL_PERIODS = closePrice.Length;
    double[] outputSma = new double[closePrice.Length];
    double[] outputStdDev = new double[closePrice.Length];
    int[] outputShootingStar = new int[closePrice.Length];
    int[] outputHangingMan = new int[closePrice.Length];
    int[] outputEngulf = new int[closePrice.Length];
    int[] outputMaxIndex = new int[closePrice.Length];
    double[] outputTrueRange = new double[closePrice.Length];
    double accProfit = 0;
    int position = 0;
    double openPosPrice = 0;
    double profit = 0;
    #endregion

    #region not sure what this code is for
    //for (int i = 0; i < closePrice.Length-TOTAL_PERIODS; i++) //had to change from -1 to -TOTAL_PERIODS
    //{
    //    openPrice[i] = (double)i;
    //    highPrice[i] = (double)i;
    //    lowPrice[i] = (double)i;
    //    closePrice[i] = (double)i;
    //}
    #endregion

    #region Technical Libary
    TicTacTec.TA.Library.Core.RetCode Sma = Core.Sma(0, closePrice.Length - 1, closePrice, SmaPeriod, out outBegIdx, out outNbElement, outputSma);
    TicTacTec.TA.Library.Core.RetCode StdDev = Core.StdDev(0, closePrice.Length - 1, closePrice, closePrice.Length, 1, out outBegIdx, out outNbElement, outputStdDev);
    TicTacTec.TA.Library.Core.RetCode ShootingStar = Core.CdlShootingStar(0, closePrice.Length - 1, openPrice, highPrice, lowPrice, closePrice, out outBegIdx, out outNbElement, outputShootingStar);
    TicTacTec.TA.Library.Core.RetCode HangingMan = Core.CdlHangingMan(0, closePrice.Length - 1, openPrice, highPrice, lowPrice, closePrice, out outBegIdx, out outNbElement, outputHangingMan);
    TicTacTec.TA.Library.Core.RetCode BullIngulf = Core.CdlEngulfing(0, closePrice.Length - 1, openPrice, highPrice, lowPrice, closePrice, out outBegIdx, out outNbElement, outputEngulf);
    TicTacTec.TA.Library.Core.RetCode TrueRange = Core.TrueRange(0, closePrice.Length - 1, highPrice, lowPrice, closePrice, out outBegIdx, out outNbElement, outputTrueRange);
    //TicTacTec.TA.Library.Core.RetCode xx = Core.bu
    //TicTacTec.TA.Library.Core.RetCode MaxIndex = Core.MaxIndex(0, closePrice.Length - 1, highPrice, 20, out outBegIdx, out outNbElement, outputMaxIndex);
    #endregion

    for (int i = 20; i < closePrice.Length - 1; i++)
    {
        for (int j = 0; j < 10; j--)
        {

        }
    }
}

3 个答案:

答案 0 :(得分:2)

您可以使用以下代码:

int[] arr = new int[200];                // Original list of lines
List<int> maxList = new List<int>();     // Result list to hold max values
int[] range = new int[10];               // Sub-list of lines to check max value
for (int i = 0; i < arr.Length - 9; i++)
{
    Array.Copy(arr, i, range, 0, 10);    // Get sub-set of lines
    maxList.Add(range.Max());            // Find max, add it to the result list
}

答案 1 :(得分:1)

你可以使用像这样的扩展方法:

public static IEnumerable<TResult> LeftSegAggregate<TItem, TResult>(
    this IEnumerable<TItem> items, 
    Func<IEnumerable<TItem>, TResult> aggregator, 
    int segmentLength)
{
    if (items == null)
        throw new ArgumentNullException("items");
    if (segmentLength <= 0)
        throw new ArgumentOutOfRangeException("segmentLength");

    int i = 0, c = 0;
    var segment = new TItem[segmentLength];
    foreach (var item in items)
    {
        c++;
        segment[i++ % segmentLength] = item;         
        yield return aggregator(segment.Take(c));
    }
}

此方法为商店当前段创建数组。 对于目标集合聚合器函数中的每个项目应用于段数组并返回下一个结果(例如,此段的最大值)。

  • 没有内存重新分配,没有复制,只是循环填充的简单数组;
  • 您可以使用任何类型的集合 - 只提供聚合功能;
  • 您可以根据需要获得尽可能多的枚举数,并在循环中使用它们;

示例:

// Sample items (some complex objects for example).
var items = new[] { 1, -3, 6, 5, -2, 0, 3, 4, 8, 0, 4, 7, 2, 9, -3 }
    .Select(
        i => new {
            Name = string.Format("Item {0}", i), 
            Value = i                        
        }
    ).ToArray();

// Get enumerator of segment max for Value field.
var segMaxEnumerator = items.LeftSegAggregate(
    // Aggregation function (returns max value from segment of items).
    seg => seg.Select(i => i.Value).Max(),
    // Size of target segment.
    10  
).GetEnumerator();

// Here is your loop:
for (var i = 0; i < items.Length; i++)
{                
    // Move segment max enumerator to next item.
    segMaxEnumerator.MoveNext();

    // Use segMaxEnumerator.Current to take segment max.
    Console.WriteLine("{0}: {1}", i, segMaxEnumerator.Current);
}

答案 2 :(得分:0)

这是LINQ中的另一个版本

var list = new List<int>();
var max = list.Select((x, i) => //get items (x as value, i as index
                  list.Skip(Math.Max(i - 10, 0)) //forget about previous items
                    .Take(Math.Min(10, i + 1)) // get 10(or less) elements before this element 
                    .Max()) // get maximum of them
              .ToList();//convert result to list

并且测试将是这样的

var l = new List<int>
{
    1, 4, 3, 8, 2, 11, 4, 3, 5, 19, 2, 8,
    11, 13, 14, 12, 12, 12, 12, 12
};
var max = l.Select((x, i) => l.Skip(Math.Max(i - 10, 0)).Take(Math.Min(10, i + 1)).Max()).ToList();
Console.WriteLine(string.Join(",", max));
//1,4,4,8,8,11,11,11,11,19,19,19,19,19,19,19,19,19,19,19,14,14,14