如果存在键子字符串,则返回字典值

时间:2015-11-26 16:36:12

标签: c# list dictionary substring

如果密钥包含一半与字符串查找匹配的字符串,我想从字典中返回值。

private readonly Dictionary<string, string> _ipAddressesDictionary = new Dictionary<string, string>()
{
       {"ip.qwer4.abc5.somename", "6x.x.00.xx"},
       {"ip.qwer3.abc1.somename", "6x.3.xx.xx"},
}

Forexample,

我有一个字符串&#34; abc1.somename&#34;,我正在构建如下逻辑 - 目前还没有工作 - 让我< strong> value 给定的密钥名称包含该子字符串。我希望得到&#34; 6x.3.xx.xx&#34;回来。

public string LookUpPeerIp(string deviceName)
{
    var value = _ipAddressesDictionary.Keys.Contains(deviceName);

    return value.ToString();
}

编辑:

对不起,伙计们,忘记提及传入的字符串来查找 并不完全匹配 。它附有一个.co.uk :(

所以它将是abc1.somename.co.uk但字典有ip.qwer3.abc1.somename而没有 .co.uk

5 个答案:

答案 0 :(得分:4)

在线试用https://dotnetfiddle.net/q6E1wR

这会削减正确的点 - 我的回答:

用法:

Console.WriteLine("--first");
Console.WriteLine(LookupByPrefix("abc1.somename.co.uk"));
Console.WriteLine("--many");
string[] many = LookupByPrefixMany("abc1.somename.co.uk");
foreach(string ip in many)
    Console.WriteLine(ip);

单个结果:

public string LookupByPrefix(string domainName)
{
    string[] dotDomains = domainName.Split('.');

    for(int matchCount = dotDomains.Length; matchCount > 0; matchCount--)
    {
        string[] ret = LookUpPeerIpMany(string.Join(".", dotDomains.Take(matchCount)));
        if(ret != null && ret.Length > 0) return ret.SingleOrDefault();
    }

    return null;
}

对于多个结果:

public string[] LookupByPrefixMany(string domainName)
{
    string[] dotDomains = domainName.Split('.');

    for(int matchCount = dotDomains.Length; matchCount > 0; matchCount--)
    {
        string[] ret = LookUpPeerIpMany(string.Join(".", dotDomains.Take(matchCount)));
        if(ret != null && ret.Length > 0) return ret;
    }

    return null;
}

相关性:

public string[] LookUpPeerIpMany(string deviceName)
{
    return _ipAddressesDictionary
           .Where(q=>q.Key.Contains(deviceName)).Select(q=>q.Value).ToArray();
}

很高兴为您服务!

答案 1 :(得分:3)

public string LookUpPeerIp(string deviceName)
{
    var keySubstringMatch = _ipAddressesDictionary.Keys
        .FirstOrDefault(key => key.Contains(deviceName));
    if(keySubstringMatch == null)
        return null;
    else
        return _ipAddressesDictionary[keySubstringMatch];
} 

可能有多个匹配,那么这将是一个很好的方法:

public IEnumerable<string> LookUpPeerIp(string deviceName)
{
    var keySubstringMatch = _ipAddressesDictionary.Keys
        .Where(key => key.Contains(deviceName));
    foreach (string key in keySubstringMatch)
        yield return _ipAddressesDictionary[key];
} 

然后您可以处理所有匹配项,例如:

string allMatching = String.Join(",", LookUpPeerIp("abc1.somename"));

答案 2 :(得分:1)

如果要返回包含字符串一部分的键的所有值(或第一个值),除了遍历所有键并返回适合您需要的键之外,您没有别的办法。那就是O(N)的复杂性。

如果不是包含,你可以用一个开头,那么字典不是一个好的选择。使用Trie可以获得更好的效果。框架中没有内置的Trie实现,但是有一些开源实现可供使用。

答案 3 :(得分:0)

这样做:

string partial = "abc5";
string value= _ipAddressesDictionary.FirstOrDefault(x => x.Key.Contains(partial)).Value;

答案 4 :(得分:0)

首先搜索完全匹配,然后搜索部分匹配。然后使用正则表达式

public string LookUpPeerIp(string deviceName)
{
        string value = null;
        _ipAddressesDictionary.TryGetValue(deviceName, out value);
        if (value != null)
            return value;

        var keyPair = _ipAddressesDictionary.FirstOrDefault(k => k.Key.Contains(value));

        if (keyPair != null)
            return keyPair.Value;

        string pattern = @"your pattern";
        Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase);

        keyPair = _ipAddressesDictionary.FirstOrDefault(k => rgx.IsMatch(k.Key));
        return keyPair != null ? keyPair.Value : null;
  }

更多关于正则表达式的信息 https://www.google.ie/?gws_rd=cr,ssl&ei=4z1XVv-oMsGsPMagotAG#q=c%23+regular+expressions