Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Linq通过键(或部分键)检索查找值的替代方法_C#_Linq - Fatal编程技术网

C# Linq通过键(或部分键)检索查找值的替代方法

C# Linq通过键(或部分键)检索查找值的替代方法,c#,linq,C#,Linq,我正在编写以下代码,根据用户指定的搜索短语查找“描述”。将键视为重要的短语,将值视为在何处查找该短语的说明。 把它想象成一个商店定位器(我能想到的最好的类比)。如果你搜索“Target”(键),你会得到成吨的城市(值),有些城市可能有相同的名字。因此,在同一个城市中可以有多个目标。 字典显然不起作用,因为我要么有重复的商店名称,要么可能有重复的城市名称。这让我想到了我的实际情况: 基本上,我从一个列表开始以允许在两个方向上重复,然后将其转换为查找,我认为这会比实际情况更容易混淆 List<

我正在编写以下代码,根据用户指定的搜索短语查找“描述”。将键视为重要的短语,将值视为在何处查找该短语的说明。
把它想象成一个商店定位器(我能想到的最好的类比)。如果你搜索“Target”(键),你会得到成吨的城市(值),有些城市可能有相同的名字。因此,在同一个城市中可以有多个目标。
字典
显然不起作用,因为我要么有重复的商店名称,要么可能有重复的城市名称。这让我想到了我的实际情况:

基本上,我从一个
列表开始
以允许在两个方向上重复,然后将其转换为
查找
,我认为这会比实际情况更容易混淆

List<KeyValuePair<string, string>> kvpList = new List<KeyValuePair<string, string>>();
Lookup<string, string> collection;

kvpList.Add(new KeyValuePair<string, string>("K1", "R1"));
kvpList.Add(new KeyValuePair<string, string>("K1", "R1"));
kvpList.Add(new KeyValuePair<string, string>("K1", "R2"));
kvpList.Add(new KeyValuePair<string, string>("K2", "R1"));
kvpList.Add(new KeyValuePair<string, string>("K2", "R2"));
kvpList.Add(new KeyValuePair<string, string>("K2", "R3"));
kvpList.Add(new KeyValuePair<string, string>("K2", "R1"));

collection = (Lookup<string,string>)kvpList.ToLookup(k => k.Key, k => k.Value);
我对上面的代码没有问题,但我的问题是:有没有一种方法可以使用Linq来实现我想要实现的目标?我觉得我所拥有的并不是最好的方法…

可能值得注意的是,部分
搜索项
也必须能够找到出现在关键字中的结果(因此包含)。现有的答案不能完全回答我的具体问题。我无法通过部分键搜索找到一个帮助我获取值的方法。

您可以使用LINQ和
哈希集,这将为您消除重复项:

var uniqueResults = collection.Where(item => item.Contains(searchTerm))
                              .SelectMany(x => x)
                              .ToHashSet();
其中
ToHashSet
是一种自定义扩展方法,您可以轻松创建:

public static class EnumerableExtensions
{
    public static HashSet<T> ToHashSet(this IEnumerable<T> enumerable)
    {
        return new HashSet<T>(enumerable);
    }
}
公共静态类EnumerableExtensions
{
公共静态HashSet到HashSet(此IEnumerable可枚举)
{
返回新的哈希集(可枚举);
}
}

翻译成LINQ的代码如下所示:

var uniqueResults = collection
        .Where(item => item.Key.Contains(searchTerm)) // filter the collection
        .SelectMany(x => x)                           // flatten results
        .Distinct()                                   // remove duplicates
        .ToList();
您甚至不需要
查找
。使用
kvpList
可以获得相同的结果:

var uniqueResults = kvpList
        .Where(item => item.Key.Contains(searchTerm)) // filter the collection
        .Select(item => item.Value)                   // get the Values from KeyValuePairs
        .Distinct()                                   // remove duplicates
        .ToList();

LINQ解决方案实际上比命令式解决方案更容易理解。尝试用英语描述您的算法:从
kvpList
中,选择键包含搜索词的不同值。这几乎就是第二个LINQ代码。

查找就像字典一样,没有子字符串搜索。如果需要子字符串搜索,则不能使用基于集合的方法,因为它们使用的
GetHashCode
无法处理部分字符串(它如何为所有子字符串返回一个值?)。我建议在您的问题中,使“部分搜索项还必须能够找到出现在关键字中的结果”更加突出,更改标题,使其成为前几段的一部分。我想,这在很大程度上塑造了这个问题。谢谢@31eee384,做出了这些改变。你错过了一个平坦的层次<问题中的code>uniqueResults
包含值,而不是HashSet的可枚举值。@CoderDennis谢谢,我错过了。没有Jakub的答案那么简单,但仍然很酷+从我这里得到1。在这里查找是无用的。OP应该只使用
kvpList
(因此用
kvpList
替换
collection
)@TimSchmelter你说得对,它比带有查找功能的版本更容易理解。我在答案中包括了这两个版本。谢谢@JakubLortz!这使得理解LINQ实现这一点的方法更加容易。当然更容易理解上下文。值得一提的是,当我试图找到这个解决方案时,我认为Select和SelectMany比其他人更容易让我受挫。
var uniqueResults = kvpList
        .Where(item => item.Key.Contains(searchTerm)) // filter the collection
        .Select(item => item.Value)                   // get the Values from KeyValuePairs
        .Distinct()                                   // remove duplicates
        .ToList();