2017-06-19 75 views
-1

有很多類似標題的問題,但沒有人回答我的問題。數組嵌套在iOS中的字典?

在我的情況我有一個數組:

[ 「1」, 「2」, 「3」, 「4」]

而得到的詞典應該是:

[「1 「:[」2「:[」3「:」4「]]]

如何正確地將其轉換?據我所知,map,reduce和類似的功能沒有這樣的功能。是否有可能不用編寫遞歸方法?

兩個Objective-C和夫特適用

+0

奇怪的問題,但有趣的:-p – csblo

+3

使用遞歸方法有什麼問題? –

+0

@DatNguyen,遞歸看起來像額外的這個任務,它似乎你也需要標記所有參數爲可變 –

回答

3

迅速解決方案,使用reduce

let a = ["1", "2", "3", "4"] 

let d = a.dropLast(2).reversed() 
    .reduce([a[a.count - 2] : a[a.count - 1]]) { [$1 : $0] } 

print(d) // ["1": ["2": ["3": "4"]]] 

這裏,假設該陣列具有至少2個元素。

在我們的例子,["3", "4"]reduce, 和以相反的順序其餘元素的初始值,嵌套字典 在封閉創建與[$1 : $0]

結果的類型是[String: Any],如果需要,可以橋接到 NSDictionary

+0

漂亮! :-p喜歡它 – csblo

+0

謝謝。但請注意 - 它不適用於'array.count <2'。你能解決這個問題嗎? –

+0

你會期望什麼結果爲空或單元素數組?您不能從0或1個元素構建字典。 –

3
//Your array 
    NSArray *a = @[@1,@2,@3,@4]; 

    //Get the two last values (considering your array length must be at least 2 ! 
    NSDictionary *last = @{a[a.count-2]:a[a.count-1]}; 

    //In reverse order we assign last created dictionary to the current key, the array length must be superior than 3 
    for (NSInteger i = a.count - 3; i >= 0; i--) 
     last = @{a[i]:last}; 

    NSLog(@"My dictionary %@", last); 
+1

是的,在ObjC中它是可能的,而不是Swift中。聲明中「last」的類型與迭代中分配給它的不同。 –

0

發現一個simplier溶液:

NSMutableArray *tempArr = [array mutableCopy]; 
while (tempArray.count > 1) { 
    id value = tempArr.lastObject; 
    [tempArr removeLastObject]; 
    NSString *key = tempArr.lastObject; 
    [tempArr removeLastObject]; 
    [tempArr addObject:@{key: value}]; 
} 
id result = tempArr.firstObject; 
0

遞歸選項。

func toNestedDictionary(arr: [String]) -> [String: Any?]? { 
    if arr.isEmpty { 
     return nil 
    } 
    else if arr.count == 1 { 
     return Dictionary(dictionaryLiteral: (arr.first!, nil)) 
    } 
    else if arr.count == 2 { 
     return Dictionary(dictionaryLiteral: (arr.first!, arr.last!)) 
    } 
    else { 
     let head = arr.first! 
     let tail = arr.dropFirst() 
     return Dictionary(dictionaryLiteral: (head, toNestedDictionary(arr: Array(tail)))) 
    } 
} 

print (toNestedDictionary(arr: ["1"]))     
// Optional(["1": nil]) 

print (toNestedDictionary(arr: ["1", "2"]))    
// Optional(["1": Optional("2")]) 

print (toNestedDictionary(arr: ["1", "2", "3"]))   
// Optional(["1": Optional(["2": Optional("3")])]) 

print (toNestedDictionary(arr: ["1", "2", "3", "4"])) 
// Optional(["1": Optional(["2": Optional(["3": Optional("4")])])]) 
0

試試下面線而沒有遞歸

NSArray *arr = @[@"1", @"2", @"3", @"4"];  
NSMutableDictionary *dic = [[NSMutableDictionary alloc] init]; 
for (int i = arr.count-2; i>=0;i--) { 
    if (i == arr.count-2) { 
     [dic setObject:arr[i+1] forKey:arr[i]]; 
    } else { 
     NSDictionary *tempDic = dic; 
     dic = @{arr[i]:tempDic}; 
    } 
} 
NSLog(@"Solution%@",dic); 
+0

謝謝,但已經發布了相同的想法代碼,甚至沒有混淆索引 –

0

這個問題可以很容易地使用遞歸程序來解決。這裏是使用Swift的解決方案;

var ary = ["1", "2", "3", "4"] 
func recursive(array:[String]) -> Any { 
    if ary.count > 1 { 
     let key = ary.removeFirst() 
     return [key : recursive(array: array)] 
    } else { 
     return array.last! 
    } 

} 
let reuslt = recursive(array: ary) 

而結果是:["1": ["2": ["3": "4"]]]

0

給出一個列表

var list = ["1", "2", "3", "4"] 

你可以寫

if let lastValue = list.popLast(), let lastKey = list.popLast() { 
    let dict = list.reversed().reduce([lastKey:lastValue]) { [$1:$0] } 
    print(dict) 
} 

結果

["1": ["2": ["3": "4"]]] 

請注意,如果列表中包含至少2個元素此代碼只能