数组中包含All规则的Linq查询

本文关键字:Linq 查询 规则 All 包含 数组 | 更新日期: 2023-09-27 18:01:19

我有一个图像列表,我想用BOTH规则搜索多个关键词

例如,如果我搜索"跳舞的孩子",我想显示一个同时包含关键字dancing和child 的项目列表

我实现了一个类似这样的查询:

List<string> target_keywords = //an array contains Keywords to Lookup 
var RuleAny_results = (from imageItem in images                     
                       select new{ imageItem,
                             Rank =target_keywords.Any(x => imageItem.Title != null && imageItem.Title.ToLower().Contains(x)) ? 5 :
                                   target_keywords.Any(x => imageItem.Name != null && imageItem.Name.ToLower().Contains(x)) ? 4 :                                  
                                0
                         }).OrderByDescending(i => i.Rank);
//exclude results with no match (ie rank=0 ) and get a Distinct set  of items
_searchResult = (from item in RuleAny_results
             where item.Rank != 0
             select item.imageItem).Distinct().ToList();

但这将返回带有target_keywords中任何项目的结果,例如,如果我在上面搜索"dancing child",代码将返回带有任何关键字dancing或child的项目列表。但我想要的列表都跳舞和儿童关键字只有

那么,我如何转换查询,使其获取包含BOTH关键字的所有记录呢?

数组中包含All规则的Linq查询

System.Linq.Enumerable::All就是您想要的。

using System.Linq;
using System.Collections.Generic;
struct ImageItem {
    public string Title { get; set; }
    public string Name { get; set; }
}
bool Contains(string toSearch, string x) {
    return toSearch != null && toSearch.ToLower().Contains(x);
}
IEnumerable<ImageItem> FilterItems(IEnumerable<string> targetKeywords, IEnumerable<ImageItem> items) {
    return items.Where(item => targetKeywords.All(x => Contains(item.Name, x) || Contains(item.Title, x)));
}

试试这个:--

您只需将语法中的Any关键字替换为All
以及两个字段中所有关键字的另一个排名条件

target_keywords.All( 替换target_keywords.Any(

List<string> target_keywords = //an array contains Keywords to Lookup 
var RuleAny_results = (from imageItem in images                     
                       select new{ imageItem,
                             Rank =target_keywords.Any(x => imageItem.Title != null && imageItem.Title.ToLower().Contains(x)) ? 5 :
                                   target_keywords.All(x => imageItem.Name != null && imageItem.Name.ToLower().Contains(x)) ? 4 :   
                                   target_keywords.All(x => (imageItem.Name != null && imageItem.Name.ToLower().Contains(x)) || imageItem.Title != null && imageItem.Title.ToLower().Contains(x)) ? 3 :                                
                                0
                         }).OrderByDescending(i => i.Rank);
//exclude results with no match (ie rank=0 ) and get a Distinct set  of items
_searchResult = (from item in RuleAny_results
             where item.Rank != 0
             select item.imageItem).Distinct().ToList();
class ImageDemo
    {
        public string Title { get; set; }
        public string Name { get; set; }
    }
    static void TestCode()
    {
        List<string> target_keywords = new List<string>(){"dancing","child"};
        List<ImageDemo> images = new List<ImageDemo>()
        {  
            new ImageDemo{Title = "dancing"}  ,
             new ImageDemo{Name = "child"}  ,
             new ImageDemo{Title = "child", Name="dancing"}  ,
             new ImageDemo{Title = "dancing", Name="child"}  ,
             new ImageDemo{Name="dancing child"} ,
             new ImageDemo{Title="dancing child"} 
        };
        var searchFuncs = target_keywords.Select(x =>
        {
            Func<ImageDemo, bool> func = (img) =>
            {
                return (img.Title ?? string.Empty).Contains(x) || (img.Name ?? string.Empty).Contains(x);
            };
            return func;
        });
        IEnumerable<ImageDemo> result = images;
        foreach (var func in searchFuncs)
        {
            result = result.Where(x => func(x));
        }
        foreach (var img in result)
        {
            Console.WriteLine(string.Format("Title:{0}  Name:{1}", img.Title, img.Name));
        }
    }

这是你现在想要的正确代码吗?