【问题标题】:LINQ : Checking against each other item in a listLINQ:检查列表中的其他项目
【发布时间】:2013-05-28 22:10:37
【问题描述】:

我有如下课程

public class Item
{   
    public long Id {get;set;}
    public long GroupingId {get;set;}
    public long Weight {get;set;}
    public long Tolerance {get;set;}
}

现在我有 Items 的列表,具有不同的分组 ID。让我们说

List<Item> items  = GetItems();

现在我需要对基于分组的 ID 进行分组,并检查该组中的每个项目。我将如何在 LINQ 中有效地做到这一点。非常感谢任何帮助。

IDictionary<long, long[]> matches = new Dictionary<long, long[]>();

foreach(groupedItems in items.GroupBy(p=>p.GroupingId))
{    
  foreach(item in groupItems)
  {
    // Check item with other items in group items 
    // and if condition is correct take those 2 items.
    // lets say the condition is 
    // (item.Weighting - other.Weighting) > item.Tolerance
    // duplicates could be removed 
    // lets condition for 1,2 is done means no need to do 2 against 1

    var currentItem = item;    
    var matchedOnes = 
         groupItems.Where(p => (Math.Abs(p.Weighting - currentItem.Weighting) > currentItem .Tolerance) && p.Id != currentItem.Id)
                   .ToList();

    if (!matchedOnes.Any())
        continue;

    matches.Add(currentItem.Id, matchedOnes .Select(p=>p.Id).ToArray());
  }
}

我确实喜欢上面,但是它给出了重复项(1,2 和 2,1 是重复项).. 我将如何删除重复检查

【问题讨论】:

  • 您到底想做什么检查?似乎您想抛出所有差异超过公差的项目,但在这种情况下,您应该将值与平均值进行比较,但与组中的其他值进行比较。在这种情况下,如果您有任何一对物品的差异超过公差,您将丢弃整个组。
  • 我需要检查组中大于项目 1 容差的两个项目的权重差异。 Math.Abs​​(item1.weighting-item2.weighting) > item1.Tolerance
  • 首先制作不同的GroupingId Like List lst = items.Select(h => h.GroupingId).Distinct().ToList();
  • 请定义答案字段。
  • @FrancescoDeLisi 我已经更新了它。没有名为 answer 的字段

标签: c# linq


【解决方案1】:

作为一个简单的更改,尝试在您的groupItems.Where(...) 行中将p.Id != answer.Id 替换为p.Id &gt; answer.Id

【讨论】:

  • 非常好,如果答案符合您的想法并且属于 groupItems。
【解决方案2】:

你是这个意思吗:

        var items = new List<Tuple<int, int>>()
        {
            new Tuple<int, int>(1, 1)
            , new Tuple<int, int>(1, 2)
            , new Tuple<int, int>(2, 2)
            , new Tuple<int, int>(2, 2)
            , new Tuple<int, int>(2, 3)
            , new Tuple<int, int>(3, 2)
            , new Tuple<int, int>(3, 3)
            , new Tuple<int, int>(4, 4)
            , new Tuple<int, int>(4, 3)
            , new Tuple<int, int>(4, 4)
        }.Select(kp => new { id = kp.Item1, data = kp.Item2 });

        var res = (
            from i1 in items
            from i2 in items
            where i1.id < i2.id
                /* Custom Filter goes there */
                && i1.data == i2.data
            select new { i1 = i1, i2 = i2 }
        );

【讨论】:

【解决方案3】:

试试这个

var pairs = Enumerable.Range(0, items.Count()).SelectMany(index => 
  items.Skip(index + 1).Select(right => new { left = items.elementAt(index), right }));

var matches = pairs.Where(item => 
               (item.left.Weight - item.right.Weight) > item.left.Tolerance);

第一部分创建所有需要比较的对,例如 (1, 2), (1, 3), (2, 3) 用于 3 个项目的集合。 第二部分选择符合您条件的对。

我还删除了您已经弄清楚的分组代码(items = groupItems)。

【讨论】:

  • 是我,还是 LINQ 导致代码完全不可读的场景?
猜你喜欢
  • 2022-01-04
  • 1970-01-01
  • 2019-01-10
  • 2011-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-14
  • 1970-01-01
相关资源
最近更新 更多