首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有没有更好的方法来做到这一点,也许用LINQ ish替换for/foreach循环?

有没有更好的方法来做到这一点,也许用LINQ ish替换for/foreach循环?
EN

Stack Overflow用户
提问于 2012-04-28 07:45:36
回答 5查看 240关注 0票数 3

我有一个现有的控股列表,我想合并在另一个控股列表。我知道使用foreach & for循环是一种不好的方法,但我想不出使用LINQ来减少这一点的好方法。

代码语言:javascript
复制
private void CombineHoldings(List<Holding> holdingsToAdd, ref List<Holding> existingHoldings)
{
    foreach (Holding holdingToAdd in holdingsToAdd)
    {
        Boolean found = false;
        for (int i = 0; i < existingHoldings.Count; i++)
        {
            if (existingHoldings[i].Sector == holdingToAdd.Sector)
            {
                found = true;
                existingHoldings[i].Percentage += holdingToAdd.Percentage;
            }
        }
        if (!found)
            existingHoldings.Add(holdingToAdd);
    }
    foreach (Holding holding in existingHoldings)
        holding.Fund = "Combined Funds";
}
EN

回答 5

Stack Overflow用户

发布于 2012-04-28 09:51:59

让函数修改原始列表使得它非常不是Linq,所以这里有一个版本,它将两个列表视为不可变的:

代码语言:javascript
复制
private List<Holding> CombineHoldings(
    List<Holding> holdingsToAdd, 
    List<Holding> existingHoldings) 
{
    var holdings = existingHoldings.Concat(holdingsToAdd)
        .GroupBy(h => h.Sector)
        .Select(g => 
        { 
            var result = g.First(); 
            result.Percentage = g.Select(h => h.Percentage).Sum();
            return result; 
        });
    return holdings.ToList();
}

肯定不会赢得性能竞赛,但我喜欢它的简单性。下面的代码可能会更快,但会更复杂,需要您覆盖控股上的相等以比较扇区或创建一个IEqualityComparer<Holding>

代码语言:javascript
复制
private List<Holding> CombineHoldings(
    List<Holding> holdingsToAdd, 
    List<Holding> existingHoldings) 
{
    var holdings = existingHoldings.GroupJoin(holdingsToAdd, h => h, h => h, 
        (h, toAdd) =>
        new Holding(
            h.Sector, 
            /*Other parameters to clone*/, 
            h.Percentage + toAdd.Select(i => i.Percentage).Sum())
        ).ToList();
    holdings.AddRange(holdingsToAdd.Except(holdings));
    return holdings;
};
票数 1
EN

Stack Overflow用户

发布于 2012-04-28 08:36:48

如果您经常在列表中调用此方法,那么我建议将其放入列表类型的扩展方法中,即

代码语言:javascript
复制
private static void CombineHoldings(this List<Holding> holdingsToAdd, ref List<Holding> existingHoldings)
{
    foreach (Holding holdingToAdd in holdingsToAdd)
    {
        Boolean found = false;
        for (int i = 0; i < existingHoldings.Count; i++)
        {
            if (existingHoldings[i].Sector == holdingToAdd.Sector)
            {
                found = true;
                existingHoldings[i].Percentage += holdingToAdd.Percentage;
            }
        }
        if (!found)
            existingHoldings.Add(holdingToAdd);
    }
    foreach (Holding holding in existingHoldings)
        holding.Fund = "Combined Funds";
}

这将允许您在创建了列表的任何位置

代码语言:javascript
复制
List<Holding> temp1 = new List<Holding>();
List<Holding> temp2 = new List<Holding>();
//add here to temp1 and temp2
//then...
temp1.CombineHoldings(temp2);

将第一个方法设为静态,并在第一个参数前面放一个'this‘关键字,这意味着它将扩展该类型

看一下参数,尽管切换这两个参数可能更有意义,这样它就会添加到调用方法的列表中,如下所示-

代码语言:javascript
复制
private static void CombineHoldings(this List<Holding> existingHoldings, List<Holding> holdingsToAdd)
票数 0
EN

Stack Overflow用户

发布于 2012-04-28 09:10:30

我可能会这样说:

代码语言:javascript
复制
private void CombineHoldings(List<Holding> holdingsToAdd, ref List<Holding> existingHoldings)
{
    // group the new holdings by sector
    var groupedHoldings = holdingsToAdd.GroupBy(h => h.Sector);

    // now iterate over the groupings
    foreach(var group in groupedHoldings) {
         // calculate the sum of the percentages in the group
         // we'll need this later
         var sum = group.Sum(h => h.Percentage);

         // get the index of a matching object in existing holdings
         var existingHoldingIndex = existingHoldings.FindIndex(h => h.Sector == group.Key);

         // yay! found one. add the sum of the group and our job's done.
         if(existingHoldingIndex >= 0) {
             existingHoldings[existingHoldingIndex].Percentage += sum;
             continue;
         }

         // didn't find one, so take the first holding in the group, set its percentage to the sum
         // and append that to the existing holdings table
         var newHolding = group[0];
         newHolding.Percentage = sum;

         existingHoldings.Add(newHolding);
    }
}

在性能方面,我不确定这是如何维持的。但它看起来更优雅一些。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10359231

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档