簡體   English   中英

C# 從數組中訪問字典值

[英]C# Access Dictionary value from array

比如說,我有一個未確定長度的string[]和一個Dictionary<string, object> ,它包含更多與其確切類型(或其他類型,這在這里無關緊要)的字典。

現在我想根據我的字符串數組更改Dictionary中字典中的值...在我的Dictionary中。

這是一個小的可視化:

string[]: { "Human", "Legs", "Walking" }
Dictionary: 
   ↳ Key "Human":
       ↳ Key "Legs":
           ↳ Key "Walking"

我想在此示例中設置鍵“Walking”的值(我們只說true

現在我的問題是:我如何在 C# 中實現這個目標?

任何答案將不勝感激,如果我想得太多,請原諒。

因為您將Object用於TValue ,所以您需要使用x is T v運算符來測試Object是否是另一個字典,例如if( x is Dictionary<String,Object> dict )

這里的困難在於,您不能將x is T v與強類型T一起使用,因為IReadOnlyDictionary<K,V>不是V的協變,即使您知道K是什么(因為 C# 和 .NET 不部分支持 -封閉的泛型類型)。

...但是如果您不需要/不想要完全類型化的類型,並且假設您的圖中的所有字典對象始終完全是Dictionary<String,Object> (而不是Dictionary<String,Int32>Dictionary<String,String> ) 那么你可以這樣做:

String[] dictPath = new[] { "Human", "Legs", "Walking" };

Dictionary<String,Object> dictGraph = ...

Object humanLegsWalkingValue = GetValueAtPath( dictGraph, dictPath );

//

static Object? GetValueAtPath( Dictionary<String,Object> root, String[] dictPath )
{
    List<String> breadcrumbs = new List<String>(); // For reporting errors.
    
    Dictionary<String,Object> current = root;
    foreach( String name in dictPath )
    {
        breadcrumbs.Add( name );
    
        if( current.TryGetValue( name, out Object? value ) )
        {
            if( value is Dictionary<String,Object> dict )
            {
                current = dict;
            }
            else
            {
                if( breadcrumbs.Count == dictPath.Length )
                {
                    return value;
                }
                else
                {
                    String valueType = value is null ? "null" : value.GetType().FullName;
                    const String MSG_FMT = "Value at \"{0}\" is not a dictionary but is actually {1}, therefore \"{2}\" is unreachable."

                    throw new InvalidOperationException( String.Format( MSG_FMT, String.Join( ".", breadcrumbs ), valueType, String.Join( ".", dictPath ) ) );
                }
            }
        }
        else
        {
            const String MSG_FMT = "Could not find name \"{0}\" at \"{1}\" therefore \"{2}\" is unreachable."

            throw new KeyNotFoundException( String.Format( MSG_FMT, name, String.Join( ".", breadcrumbs ), String.Join( ".", dictPath ) ) );
        }
    } 

}

設置一個值,它使用幾乎完全相同的邏輯來遍歷字典圖,除了它在dictPath末尾前停止 1 步並使用它來設置current中的條目:

static void SetValueAtPath( Dictionary<String,Object> root, String[] dictPath, Object newValue )
{
    List<String> breadcrumbs = new List<String>(); // For reporting errors.
    
    Dictionary<String,Object> current = root;
    foreach( ( String name, Int32 idx ) in dictPath.Select( ( n, i ) => ( n, i ) ) )
    {
        breadcrumbs.Add( name );
    
        if( idx == dictPath.Length - 1 )
        {
            current[ name ] = newValue;
            return;
        }
        else if( current.TryGetValue( name, out Object? value ) )
        {
            if( value is Dictionary<String,Object> dict )
            {
                current = dict;
            }
            else
            {
                String valueType = value is null ? "null" : value.GetType().FullName;
                const String MSG_FMT = "Value at \"{0}\" is not a dictionary but is actually {1}, therefore {2} is unreachable."

                throw new InvalidOperationException( String.Format( MSG_FMT, String.Join( ".", breadcrumbs ), valueType, String.Join( ".", dictPath ) );
            }
        }
        else
        {
            const String MSG_FMT = "Could not find name \"{0}\" at \"{1}\" therefore \"{2}\" is unreachable."

            throw new KeyNotFoundException( String.Format( MSG_FMT, name, String.Join( ".", breadcrumbs ), String.Join( ".", dictPath ) ) );
        }
    } 

}

這可能不是您問題的(直接)答案:


string[] strs = new string[] { "Human", "Legs", "Walking" };

Dictionary<string,string> dict = new Dictionary<string, string>();

for(int i=0; i<strs.Length; i++) {
    dict.Add(strs[i],(i>0?strs[i-1]:""));
}

string find = "Human";

if(dict.ContainsKey(find)) {
    System.Console.WriteLine($"Hello: {find}");
    foreach (var item in dict.Where(x=>x.Value==find))
    {
        System.Console.WriteLine($"You have: {item.Key}");
        foreach (var item2 in dict.Where(x=>x.Value==item.Key)) 
        {
            System.Console.WriteLine($"Which can make you: {item2.Key}");
        }
    }
}
else
{
    System.Console.WriteLine($"Could not find: {find}");
}

output:

Hello: Human
You have: Legs
Which can make you: Walking

注意:目前還不清楚為什么你的問題的標題有Dictionary並且你開始定義一個數組( string[] )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM