【问题标题】:LINQ 'in' clause for child object properties子对象属性的 LINQ 'in' 子句
【发布时间】:2012-06-27 15:21:43
【问题描述】:

使用以下对象层次结构,我需要确认每个SearchResultInventories 中是否存在所有字符串Id 值,例如

给定string[] list = { "123", "234", "345" },确认所有list 值在Inventory 元素数组中至少出现一次。我很好奇是否可以使用一个 LINQ 语句来清理它。

SearchResult
--
Inventory[] Inventories

Inventory
--
String Id

现在,我正在拆分 list,例如

list.Split(').ToDictionary(i => i.ToString(), i => false)

并迭代字典,测试每个库存。然后,我创建一个新的List<SearchResult> 并在字典中没有剩余值的情况下添加项目。这感觉很笨重。

代码

// instock: IEnumerable<SearchResult>
foreach (var result in instock)
{
    Dictionary<string, bool> ids = list.Split(',').ToDictionary(i => i.ToString(), i => false);
    foreach (var id in ids)
        if (result.Inventory.Any(i => i.Id == id.Key))
            ids[id.Key] = true;

    if (!ids.Any(i => i.Value == false))
        // instockFiltered: List<SearchResult>
        instockFiltered.Add(result);
}

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    这是我写的一些代码。这里的优点是它使用哈希映射,因此理论上具有线性复杂度。

        public static bool ContainsAll<T>(this IEnumerable<T> superset, IEnumerable<T> subset, IEqualityComparer<T> comparer)
        {
            var set = new HashSet<T>(superset, comparer);
            return set.IsSupersetOf(subset);
        }
    

    【讨论】:

    • 我什至没有想到这一点;似乎 LINQ 对人们有一种“如果你只有一把锤子,那么一切看起来都像拇指”的效果。
    【解决方案2】:

    这部分 LINQ 将遍历整个库存,然后询问库存(如果它不为空)并找到包含列表中值之一的库存。

    var matches = instock.Where(stock => stock.Inventory != null && stock.Inventory.All(i => list.Contains(i.Id));
    

    【讨论】:

    • instockSearchResult 的集合。 Inventory 对象定义了有问题的 Id
    • 这不只是确认Id 值中的任一个 存在吗?我需要确认所有都在场。
    • 我的编辑没有被采纳,Any 调用应该是All
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    相关资源
    最近更新 更多