【问题标题】:How to get a NSDictionary with NSArray with file paths?如何使用带有文件路径的 NSArray 获取 NSDictionary?
【发布时间】:2025-11-25 00:50:02
【问题描述】:

我有一个如下所示的 NSArray:

@[@"file1", @"directory/testfile", @"directory/otherdir/testfile", @"otherdir/", @"otherdir/otherfile"]

我正在尝试将其转换为如下所示的 NSDictionary:

 @{
  @"directory/":@{
    @"otherdir/":@{
      @"testfile":[..some array with data..]}
    },
    @"testfile":[..some array with data..]
  },
  @"otherdir/":@{
    @"otherfile":[..some array with data..]
  },
  @"file1":[..some array with data..]
}

基本上,一个看起来像文件树的 NSDictionary。提前致谢!

编辑:我拥有的实际数组是这样的:

(
    "blog/",
    "blog/code.css",
    "blog/style.css",
    "etc/",
    "etc/awsservices.png",
    "etc/speeds.png",
    "etc/test/",
    "etc/test/other/",
    "etc/test/other/speeds.png",
    "site/",
    "site/dino.png",
    "site/error.css",
    "site/main.css",
    "site/signet.min.js"
)

以及我为此编写的代码:

-(NSDictionary*)buildDictionaryWithContentsOfPath:(NSMutableArray*)files {
    NSString *subDir;
    NSMutableDictionary *returnable = [[NSMutableDictionary alloc] initWithDictionary:@{}];
    BOOL directory;

    NSLog(@"%@", files);

    for (S3ObjectSummary *objectSummary in files) {

        if ([[objectSummary key] hasSuffix:@"/"]) {

            if (subDir && [[objectSummary key] hasPrefix:subDir]) {
                NSLog(@"prefixed %@", [objectSummary key]);
                NSMutableDictionary *treeDict = [[NSMutableDictionary alloc] initWithDictionary:@{}];

                [returnable[subDir] setObject:treeDict forKey:[objectSummary key]];

            } else {
                subDir = [objectSummary key];
                NSLog(@"dir %@", [objectSummary key]);
                NSMutableDictionary *treeDict = [[NSMutableDictionary alloc] initWithDictionary:@{}];
                [returnable setObject:treeDict forKey:[objectSummary key]];
            }
            directory = true;

        } else {
            S3GetObjectMetadataRequest *getMetadataRequest = [[S3GetObjectMetadataRequest alloc] initWithKey:[objectSummary key] withBucket:self.bucket.name];
            S3GetObjectMetadataResponse *getMetadataResponse = [self.client getObjectMetadata:getMetadataRequest];

            if (![[objectSummary key] hasPrefix:subDir]) {
                NSLog(@"file %@",[objectSummary key]);
                [returnable setObject:@{@"filename":[objectSummary key], @"directory":@(directory), @"created_at":getMetadataResponse.lastModified} forKey:[objectSummary key]];
            } else {
                for (NSString __strong *pathComp in [[objectSummary key] pathComponents]) {
                    pathComp  = [NSString stringWithFormat:@"%@/", pathComp];
                    NSLog(@"path component %@", pathComp);
                    if (![[objectSummary key] hasSuffix:@"/"]) {
                        if (returnable[pathComp]) {
                            NSLog(@"has comp %@", pathComp);
                            [returnable[pathComp] setObject:@{@"filename":[objectSummary key], @"directory":@(directory), @"created_at":getMetadataResponse.lastModified} forKey:[objectSummary key]];
                        }
                    }

                }

            }
            directory = false;
        }



        //[self.fileTree addObject:@{@"filename":[objectSummary key], @"directory":@(directory), @"created_at":getMetadataResponse.lastModified}];

    }
    return returnable;

}

以及它返回的字典:

{
    "blog/" =     {
        "blog/code.css" =         {
            "created_at" = "2013-12-07 12:13:37 +0000";
            directory = 0;
            filename = "blog/code.css";
        };
        "blog/style.css" =         {
            "created_at" = "2013-12-07 12:13:36 +0000";
            directory = 0;
            filename = "blog/style.css";
        };
    };
    "etc/" =     {
        "etc/awsservices.png" =         {
            "created_at" = "2013-12-07 12:26:37 +0000";
            directory = 0;
            filename = "etc/awsservices.png";
        };
        "etc/speeds.png" =         {
            "created_at" = "2013-12-07 13:29:27 +0000";
            directory = 0;
            filename = "etc/speeds.png";
        };
        // PROBLEM HERE
        "etc/test/" =         {
        };
        "etc/test/other/" =         {
        };
        "etc/test/other/speeds.png" =         {
            "created_at" = "2013-12-07 17:29:21 +0000";
            directory = 0;
            filename = "etc/test/other/speeds.png";
        };
        // PROBLEM HERE
    };
    "site/" =     {
        "site/dino.png" =         {
            "created_at" = "2013-12-07 12:13:59 +0000";
            directory = 0;
            filename = "pmerino/dino.png";
        };
        "site/error.css" =         {
            "created_at" = "2013-12-07 12:13:59 +0000";
            directory = 0;
            filename = "pmerino/error.css";
        };
        "site/main.css" =         {
            "created_at" = "2013-12-07 12:13:59 +0000";
            directory = 0;
            filename = "pmerino/main.css";
        };
        "site/signet.min.js" =         {
            "created_at" = "2013-12-07 12:13:59 +0000";
            directory = 0;
            filename = "pmerino/signet.min.js";
        };
    };
}

如你所见,这部分:

"etc/test/" =         {
};
"etc/test/other/" =         {
};
"etc/test/other/speeds.png" =         {
    "created_at" = "2013-12-07 17:29:21 +0000";
    directory = 0;
    filename = "etc/test/other/speeds.png";
};

应该是这样的:

"etc/" =         {
  "test/" =         {
    "other/" = {
      "speeds.png" =         {
          "created_at" = "2013-12-07 17:29:21 +0000";
          directory = 0;
          filename = "etc/test/other/speeds.png";
      };
    };
  };
};

【问题讨论】:

  • 我很难看到NSArray 示例和NSDictionary 示例之间的关系...
  • @nhgrif 好吧,我制作的字典是我试图获取数组的字典。它在技术上是伪代码。 NSArray 内容是文件夹和文件的文件名。
  • 发布您迄今为止为进行转换所做的尝试。
  • “some array with data”的数组中究竟是什么?
  • 查看更新后的帖子

标签: ios nsarray nsdictionary filetree


【解决方案1】:

如果我正确理解您的问题,这种方法应该会有所帮助:

// Add the path to the tree. Returns the "node" for this path.
-(NSMutableDictionary *)addFile:(NSString *)path toTree:(NSMutableDictionary *)tree
{
    NSMutableDictionary *node = tree;

    // Split path into components:
    NSArray *components = [path componentsSeparatedByString:@"/"];

    // Create all intermediate dictionaries:
    for (NSUInteger i = 0; i < [components count] - 1; i++) {
        NSString *key = [components[i] stringByAppendingString:@"/"];
        if (node[key] == nil) {
            node[key] = [NSMutableDictionary dictionary];
        }
        node = node[key];
    }

    // Process last component, which is the file name,
    // or "" in the case of a dictionary:
    NSString *name = [components lastObject];
    if ([name length] > 0) {
        node[name] = [NSMutableDictionary dictionary];
        node = node[name];
    }
    return node;
}

如果你这样使用它:

NSArray *files = ...; // Your array of files
NSMutableDictionary *tree = [NSMutableDictionary dictionary];
for (NSString *path in files) {
    NSMutableDictionary *node = [self addFile:path toTree:tree];
    BOOL isDir = [path hasSuffix:@"/"];
    if (!isDir) {
        node[@"filename"] = path;
    }
}

结果字典是

{ “博客/” = { “代码.css” = { 文件名=“博客/code.css”; }; “样式.css” = { 文件名 = "博客/style.css"; }; }; “等/” = { “awsservices.png”= { 文件名 = "etc/awsservices.png"; }; “速度.png”= { 文件名 = "etc/speeds.png"; }; “测试/” = { “其他/” = { “速度.png”= { 文件名 = "etc/test/other/speeds.png"; }; }; }; }; “网站/” = { “恐龙.png” = { 文件名 = "网站/dino.png"; }; “错误.css” = { 文件名=“站点/error.css”; }; “main.css” = { 文件名=“站点/main.css”; }; "signet.min.js" = { 文件名=“站点/signet.min.js”; }; }; }

【讨论】:

  • 太棒了,非常感谢,这几天我一直在努力解决这个问题:)
最近更新 更多