类型'any'没有下标成员错误的地图

时间:2016-09-25 17:38:03

标签: arrays swift dictionary nsuserdefaults

我已经尝试了几个小时的各种可能的组合,但无法让它发挥作用。

我的职能:

public class Library {
public static void main(String [] arg){
    System.out.println("Please Enter A Number Of Members:");
    Scanner s=new Scanner (System.in);
    int numOfMembers=s.nextInt();
    String name [] =new String[numOfMembers];
    int ID[]=new int[numOfMembers]; 
    add();
}
static void add(){
    System.out.println("Enter Name Of Member:");
    Scanner s2=new Scanner(System.in);
    boolean x=true;
    int i=0;
    while(x==true){
        if(name[i]==null){
            name[i]=s2.nextLine();
            x=false;}
            else{ 
                i++;
            }
        }
    }

}

给我错误'type'Any'没有下标成员。 我已经研究并试图改变:

func allItems() -> [TodoItem] {
    let todoDictionary = UserDefaults.standard.dictionary(forKey: ITEMS_KEY) ?? [:]
    let items = Array(todoDictionary.values)

    return items.map({TodoItem(
        deadline: $0["deadline"] as! Date,
        title: $0["title"] as! String, 
        UUID: $0["UUID"] as! String!,
        description: $0["description"] as! String,
        imageSavePath: ($0["imageSavePath"] as! String),
        isItComplete: $0["isItComplete"] as! Bool
    )}).sorted(by: {(left: TodoItem, right:TodoItem) -> Bool in
        (left.deadline.compare(right.deadline) == .orderedAscending)
    })
}

func allItems() -> [TodoItem]

然而,这引发了'Type Any不符合Hashable协议'的错误。这是正确的路线吗?

请在我的Macbook出现之前帮助.....!

2 个答案:

答案 0 :(得分:2)

注意变量的类型。

dictionary(forKey:)返回[String: Any],因此todoDictionary[String: Any]

(在较旧的Swift中,通用字典的值类型导入为AnyObject,但现在它是Any。)

您只检索值并将其转换为数组,因此itemsArray<Any>

然后,您将map应用于items,因此其中$0Any

因此,您无法将任何方法(包括下标)应用于Any

如果您需要应用$0["deadline"]或某些内容且值可能不同,则$0的类型必须是字典,其键类型为String且其值类型为混合,其中在Swift 3中由Any表示。

$0类型必须为[String: Any],因此items的类型必须为Array<[String: Any]>(又名[[String: Any]])。

这意味着todoDictionary的值类型必须为[String: Any],其密钥类型已经限制为String,因此todoDictionary的类型必须为[String: [String: Any]] 1}}。

结论,将allItems()的第一行更改为:

let todoDictionary = UserDefaults.standard.dictionary(forKey: ITEMS_KEY) as? [String: [String: Any]] ?? [:]

答案 1 :(得分:0)

您只从字典中取出values。您之后尝试使用字符串下标这些Any个实例,因为编译器不知道这些Any实例是否保证为Dictionaries或其他任何可以由String订阅的内容。

您的问题非常缺乏,并且无法转换您实际尝试实现的目标。我怀疑您是否正在尝试将[String: [String: Any]]映射到[String: TodoItem],以下是您的问题:

func allItems() -> [TodoItem] {
    let todoDictionary = UserDefaults.standard.dictionary(forKey: ITEMS_KEY) ?? [:] //inferred type: [String: Any]
    let items = Array(todoDictionary.values) //inferred type [Any]

    return items.map({TodoItem(
        deadline: $0["deadline"] as! Date, //[Any] can only be subscripted by indices, not by string.
        title: $0["title"] as! String, 
        UUID: $0["UUID"] as! String!,
        description: $0["description"] as! String,
        imageSavePath: ($0["imageSavePath"] as! String),
        isItComplete: $0["isItComplete"] as! Bool
    )}).sorted(by: {(left: TodoItem, right:TodoItem) -> Bool in
        (left.deadline.compare(right.deadline) == .orderedAscending)
    })
}