为了账号安全,请及时绑定邮箱和手机立即绑定

查找实例在列表中出现的次数

查找实例在列表中出现的次数

C#
繁华开满天机 2023-05-13 16:11:13
我有一个列表,我的目标是确定该列表中的值超过特定值的次数。例如,如果我的列表是: List = {0, 0, 3, 3, 4, 0, 4, 4, 4} 我想知道有两个实例,我在列表中的值大于 2 并保持在上面2. 所以在这种情况下有 2 个实例,因为它一度低于 2 并再次高于它。    private void Report_GeneratorButton_Click(object sender, EventArgs e)    {        //Lists        var current = _CanDataGraph._DataPoints[CanDataGraph.CurveTag.Current].ToList();        var SOC = _CanDataGraph._DataPoints[CanDataGraph.CurveTag.Soc].ToList();        var highcell = _CanDataGraph._DataPoints[CanDataGraph.CurveTag.HighestCell].ToList();        var lowcell = _CanDataGraph._DataPoints[CanDataGraph.CurveTag.LowestCell].ToList();        //Seperates current list into charging, discharging, and idle        List<double> charging = current.FindAll(i => i > 2);        List<double> discharging = current.FindAll(i => i < -2);        List<double> idle = current.FindAll(i => i < 2 && i > -2);        //High cell        List<double> overcharged = highcell.FindAll(i => i > 3.65);        int ov = overcharged.Count;        if (ov > 1)        {            Console.WriteLine("This Battery has gone over Voltage!");        }        else        {            Console.WriteLine("This battery has never been over Voltage.");        }        //Low cell        List<double> overdischarged = lowcell.FindAll(i => i > 3.65);        int lv = overdischarged.Count;        if (lv > 1)        {            Console.WriteLine("This Battery has been overdischarged!");        }        else        {            Console.WriteLine("This battery has never been overdischarged.");        }        //Each value is 1 second        int chargetime = charging.Count;        int dischargetime = discharging.Count;        int idletime = idle.Count;        Console.WriteLine("Charge time: " + chargetime + "s" + "\n" + "Discharge time: " + dischargetime + "s" + "\n" + "Idle time: " + idletime);    }我当前的代码是这样并输出:    This battery has never been over Voltage.    This battery has never been overdischarged.    Charge time: 271s    Discharge time: 0s    Idle time: 68
查看完整描述

4 回答

?
蛊毒传说

TA贡献1895条经验 获得超3个赞

有很多方法可以解决这个问题;我的建议是将它分解成许多较小的问题,然后编写一个简单的方法来解决每个问题。


这是一个更简单的问题:给定一个序列T,给我返回一个删除了“双倍”项目的序列T:


public static IEnumerable<T> RemoveDoubles<T>(

  this IEnumerable<T> items) 

{

  T previous = default(T);

  bool first = true;

  foreach(T item in items)

  {

    if (first || !item.Equals(previous)) yield return item;

    previous = item;

    first = false;

  }

}

伟大的。这有什么帮助?因为现在解决您的问题是:


int count = myList.Select(x => x > 2).RemoveDoubles().Count(x => x);

跟着。


如果您有myListas{0, 0, 3, 3, 4, 0, 4, 4, 4}那么结果Select是{false, false, true, true, true, false, true, true, true}.


的结果RemoveDoubles是{false, true, false, true}。


的结果Count是 2,这是期望的结果。


尽可能使用现成的部件。如果你不能,试着解决一个简单的、一般的问题,让你得到你需要的东西;现在您有了一个工具,您可以将其用于需要您删除序列中重复项的其他任务。


查看完整回答
反对 回复 2023-05-13
?
蓝山帝景

TA贡献1843条经验 获得超7个赞

该解决方案应该可以达到预期的效果。


    List<int> lsNums = new List<int>() {0, 0, 3, 3, 4, 0, 4, 4, 4} ;

    public void MainFoo(){

        int iChange = GetCritcalChangeNum(lsNums, 2);

        Console.WriteLine("Critical change = %d", iChange);

    }

    public int GetCritcalChangeNum(List<int> lisNum, int iCriticalThreshold) { 

        int iCriticalChange = 0;

        int iPrev = 0;

        lisNum.ForEach( (int ele) => { 

            if(iPrev <= iCriticalThreshold && ele > iCriticalThreshold){

                iCriticalChange++;

            }

            iPrev = ele;

        });


        return iCriticalChange;

    }


查看完整回答
反对 回复 2023-05-13
?
30秒到达战场

TA贡献1828条经验 获得超6个赞

您可以创建一个扩展方法,如下所示。


public static class ListExtensions

{

    public static int InstanceCount(this List<double> list, Predicate<double> predicate)

    {

        int instanceCount = 0;

        bool instanceOccurring = false;


        foreach (var item in list)

        {

            if (predicate(item))

            {

                if (!instanceOccurring)

                {

                    instanceCount++;

                    instanceOccurring = true;

                }

            }

            else

            {

                instanceOccurring = false;

            }

        }


        return instanceCount;

    }

}

并像这样使用您新创建的方法


current.InstanceCount(p => p > 2)


查看完整回答
反对 回复 2023-05-13
?
手掌心

TA贡献1942条经验 获得超3个赞

执行此操作的另一种方法System.Linq是遍历列表,同时选择itemitself 和 it's index,然后返回true每一项大于value且前一项小于或等于 的项value,然后选择结果数true。当然索引有一个特例0,我们不检查前一项:


public static int GetSpikeCount(List<int> items, int threshold)

{

    return items?

        .Select((item, index) =>

            index == 0

                ? item > threshold

                : item > threshold && items[index - 1] <= threshold)

        .Count(x => x == true)  // '== true' is here for readability, but it's not necessary

           ?? 0;  // return '0' if 'items' is null

}   

示例用法:


private static void Main()

{

    var myList = new List<int> {0, 0, 3, 3, 4, 0, 4, 4, 4};

    var count = GetSpikeCount(myList, 2);

    // count == 2

}


查看完整回答
反对 回复 2023-05-13
  • 4 回答
  • 0 关注
  • 123 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信