我正在开发一个需要tableView
分类杂货商品列表的项目。每个类别都可以具有 n 深度。来自API的JSON
响应如下所示。
"items":[
{
"id":"5366f8d3e4b0e44dc2d4a6fb",
"name":"String Cheese"
"description":"Sargento String Cheese",
"categorization":[
[
"Dairy",
"Cheese"
]
]
},
{
"id":"5366f8d3e4b0e44dc2d1a6fb",
"name":"Budlight 6-pk"
"description":"Budlight 12-pk",
"categorization":[
[
"Beverages",
"Alcohol",
"Beer"
]
]
}
]
现在我从项目词典创建Item对象并将它们存储在如下所示的可变数组中。
NSArray *itemsArray = [response objectForKey:items];
NSMutableArray *itemsMutableArray = [[NSMutableArray alloc] init];
for(NSDictionary *itemDict in itemsArray){
Item *itemObj = [[Item alloc] initWithDictionary:itemDict]
[itemsMutableArray addObject:itemObj];
}
我想遍历itemsMutableArray
并创建一个树数据结构,其中包含从根到每个项的路径。然后,我希望能够在每个级别的类别中将树用作tableViews
的数据源。
这是我的Item类标题的样子。
@interface Item : NSObject
@property (nonatomic, strong) NSString *id;
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *description;
@property (nonatomic, strong) NSArray *categorization;
@end
......和实施
#import "Item.h"
@implementation Item
- (id)initWithDictionary:(NSDictionary *)objDictionary{
if (self = [super init]) {
self.id = [objDictionary valueForKey:@"id"];
self.name = [objDictionary valueForKey:@"name"];
self.description = [objDictionary valueForKey:@"description"];
self.categorization = [objDictionary valueForKey:@"categorization"];
}
return self;
}
@end
我对树数据结构和递归不是很熟悉。我非常感谢有关如何处理此问题的任何帮助。谢谢!
答案 0 :(得分:0)
如果需要简单的节点树数据结构。这样怎么样? 希望这一点帮助。
标题
@interface ItemCategory : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic) ItemCategory *parent;
@property (nonatomic, strong) NSMutableArray *children;
-(id)initWithName:(NSString *)n parent:(ItemCategory *)p;
@end
@interface CategoryTree : NSObject
@property (nonatomic, strong) ItemCategory *root;
-(ItemCategory *)_getChildCategory:(ItemCategory *)category name:(NSString *)name;
-(ItemCategory *)_addChildCategory:(ItemCategory *)category name:(NSString *)name;
-(void)_dumpCategory:(ItemCategory *)category depth:(int)depth;
-(void)dump;
-(ItemCategory *)getCategory:(NSArray *)arr;
-(void)addCategory:(NSArray *)arr;
@end
来源
@implementation CategoryTree
@synthesize root;
-(id)init {
if (self = [super init]) {
root = [[ItemCategory alloc] initWithName:@"root" parent:nil];
}
return self;
}
-(ItemCategory *)_getChildCategory:(ItemCategory *)category name:(NSString *)name {
for (ItemCategory *child in category.children)
if ([child.name isEqualToString:name])
return child;
return nil;
}
-(ItemCategory *)_addChildCategory:(ItemCategory *)category name:(NSString *)name {
ItemCategory *child = [self _getChildCategory:category name:name];
if (child)
return child;
child = [[ItemCategory alloc] initWithName:name parent:category];
[category.children addObject:child];
return child;
}
-(void)_dumpCategory:(ItemCategory *)category depth:(int)depth{
NSString *parentStr = @"";
ItemCategory *parent = category.parent;
while (parent) {
parentStr = [NSString stringWithFormat:@"%@%@%@", parent.name, parentStr.length > 0 ? @">" : @"", parentStr];
parent = parent.parent;
}
NSLog(@"%@%@%@", parentStr, parentStr.length > 0 ? @">" : @"", category.name);
for (ItemCategory *child in category.children) {
[self _dumpCategory:child depth:depth + 1];
}
}
-(void)dump {
[self _dumpCategory:root depth:0];
}
-(ItemCategory *)getCategory:(NSArray *)arr {
ItemCategory *category = root;
for (NSString *categoryName in arr) {
category = [self _getChildCategory:category name:categoryName];
if (!category)
return nil;
}
return category;
}
-(void)addCategory:(NSArray *)arr {
if ([self getCategory:arr])
return;
ItemCategory *category = root;
for (NSString *categoryName in arr) {
ItemCategory *childCategory = [self _getChildCategory:category name:categoryName];
if (!childCategory) {
childCategory = [self _addChildCategory:category name:categoryName];
}
category = childCategory;
}
}
@end
用法
CategoryTree *tree = [[CategoryTree alloc] init];
[tree addCategory:@[@"Dairy", @"Cheese"]];
[tree addCategory:@[@"Dairy", @"Milk"]];
[tree addCategory:@[@"Beverages", @"Alcohol", @"Beer"]];
[tree addCategory:@[@"Beverages", @"Alcohol", @"Wine"]];
[tree addCategory:@[@"Beverages", @"Non-Alcohol", @"Cola"]];
[tree dump];
结果
root
root>Dairy
root>Dairy>Cheese
root>Dairy>Milk
root>Beverages
root>Beverages>Alcohol
root>Beverages>Alcohol>Beer
root>Beverages>Alcohol>Wine
root>Beverages>Non-Alcohol
root>Beverages>Non-Alcohol>Cola
答案 1 :(得分:0)
我找到了实现你需要的方法。我不知道它是如何优化的,因为我没有收到多少物品。实施如下。
您需要先在Item.h @property (nonatomic, strong) NSMutableDictionary *catTree;
接下来这样做以获取树
[itemsMutableArray enumerateObjectsUsingBlock:^(Item *itm, NSUInteger i,BOOL *stop){
itm.catTree = [NSMutableDictionary dictionary];
NSString *dairy = @"",*beverage = @"";
for (NSArray *catArray in itm.categorization) {
/*
Everything below is written assuming the format of the JSON will be "as-is"
*/
if ([catArray containsObject:@"Dairy"]) {
//Take everything except Dairy
NSArray *stripedArray = [catArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF != \"Dairy\""]];
int i = 0;
//Loop through the array to get any sub categories.
while (i < stripedArray.count) {
dairy = [dairy stringByAppendingString:[NSString stringWithFormat:(i == stripedArray.count-1)?@"%@ ":@"%@->",stripedArray[i]]]; //Space at the end to account for similar entry in the same category for e.g two dairy products.
i++;
}
} else if ([catArray containsObject:@"Beverages"]) {
NSArray *stripedArray = [catArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF != \"Beverages\""]];
int i = 0;
while (i < stripedArray.count) {
beverage = [beverage stringByAppendingString:[NSString stringWithFormat:(i == stripedArray.count-1)?@"%@ ":@"%@->",stripedArray[i]]];
i++;
}
}
}
//Set the category tree for every item using a dictionary
[itm.catTree setValue:dairy forKey:@"Dairy"];
[itm.catTree setValue:beverage forKey:@"Beverage"];
NSLog(@"%@",itm.catTree);
}];
上面的代码为你的json提供了以下输出
{
Beverage = "";
Dairy = "Cheese ";
}
{
Beverage = "Alcohol->Beer ";
Dairy = "";
}
适用于多种饮料
{
Beverage = "Alcohol->Beer Alcohol->Wine->Red Soda->Coke ";
Dairy = "";
}
希望这有帮助。