Linq在多个字段的列表中标记重复项

时间:2018-01-21 07:48:54

标签: c# linq

从另一个进程导入func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "BlueCell") as! PeripheralTableViewCell if indexPath.section == 0 { let peripheral = self.peripherals[indexPath.row] cell.peripheralLabel?.text = peripheral.name != nil ? peripheral.name : "nil" } else { let connectedPeripheral = self.connectPeripherals[indexPath.row] cell.peripheralLabel?.text = connectedPeripheral.name != nil ? connectedPeripheral.name : "nil" } print("tableview連線有\(connectPeripherals.count)個") print("tableview未連線有\(peripherals.count)個") return cell } 的列表,商定的规则规定每个批处理在组合字段中不能有重复项 1 - Product,2 - Name和3 - Category 如果找到重复项,则每个列表项Section字段都设置为Status,我们找到了重复项。

下面的代码是我尝试使用Linq它确实返回了正确的结果,但它感觉不顺畅并且难以维护。我想使它更通用,可读和可扩展,这是否是添加扩展方法传递列以验证重复项的适当位置?如果是这样的话会是什么样的?

-1

2 个答案:

答案 0 :(得分:2)

乍一看我无法理解你的逻辑。该解决方案将更好地提高可读性和可维护性。

foreach (Product product in productList) 
{
    int dupCount = productList.Count(p => p.Name == product.Name 
                                     && p.Category == product.Category 
                                     && p.Section == product.Section);
    if (dupCount > 1) 
        product.Status = (int)ImportStatus.Duplicate;
}

编辑: 使用LINQ表达式并不总是更好,尤其是当您调用多个.Where(),. Select()和.GroupBy()时。当我们可以在这里利用循环时,不要总是排除循环。在此解决方案中,您可以避免浪费任何额外的空间来引入另一个数据结构来保存新的过滤产品列表。此外,我们可以保留原始对象,而不是实例化新的Product对象,而只是更新其Status属性。

答案 1 :(得分:1)

无需重新创建所有产品。最有效的方法是遍历具有重复项的产品并设置其Status属性:

foreach (var product in productList
    .Where (p => p.Status == 0)
    .GroupBy (p => new { p.Name, p.Category, p.Section },
        (grp, tbl) => new { GROUP= grp, TBL= tbl } )
    .Where (g => g.TBL.Count() > 1)
    .SelectMany(g => g.TBL).ToList())
{
    product.Status = -1;
}