最近几天,我遇到了一个我无法解决的问题。 实际上,我在JSON中有一些数据。我解析了这个JSON,一切正常。
以下是此JSON的结构:
{
"obs" : [
{
"CategoryId": 1,
"Title": "Category 1",
"Description": "Description 1",
"ParentCategoryId": null
},
{
"CategoryId": 2,
"Title": "Category 2",
"Description": "Description 2",
"ParentCategoryId": null
},
{
"CategoryId": 3,
"Title": "Category 3",
"Description": null,
"ParentCategoryId": null
},
{
"CategoryId": 4,
"Title": "Category 1.1",
"Description": "Description 1.1",
"ParentCategoryId": 1
},
{
"CategoryId": 5,
"Title": "Category 1.2",
"Description": "Description 1.2",
"ParentCategoryId": 1
},
{
"CategoryId": 6,
"Title": "Category 1.1.1",
"Description": null,
"ParentCategoryId": 4
},
{
"CategoryId": 7,
"Title": "Category 1.1.2",
"Description": null,
"ParentCategoryId": 4
},
{
"CategoryId": 8,
"Title": "Category 1.1.1.1",
"Description": null,
"ParentCategoryId": 6
},
{
"CategoryId": 9,
"Title": "Category 1.3",
"Description": "Category 1.3",
"ParentCategoryId": 1
}
]
}
我对这些对象的模型(.h)我正在使用librairie JSONModel:
@class CategoryModel;
@protocol CategoryModel @end
@interface CategoriesModel : JSONModel
@property (nonatomic, strong) NSArray<CategoryModel> * obs;
@end
@interface CategoryModel : JSONModel
@property (nonatomic, strong) NSNumber * CategoryId;
@property (nonatomic, strong) NSString * Title;
@property (nonatomic, strong) NSString<Optional> * Description;
@property (nonatomic, strong) NSNumber<Optional> * ParentCategoryId;
@end
然后,在视图控制器中,在获取JSON的数据并解析它之后,我想制作一个NSDictionary,NSArray或类似树的东西,例如在UITableView中显示这些类别。
我的问题是:我找不到解决方案来“排序”这些数据,并用这个做一棵树。
这是我现在的方法:
- (void)parseJSON
{
NSError * error;
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"list" ofType:@"json"];
NSString *jsonString = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:&error];
self.myJSON = [[CategoriesModel alloc] initWithString:jsonString error:&error];
for(CategoryModel * obs in self.myJSON.obs)
{
if(obs.ParentCategoryId)
{
CategoryModel * parent = [self searchParentObjectForChild:obs];
NSLog(@"Parent of %@(ID:%ld) : %@(ID:%ld)", obs.Title, [obs.CategoryId integerValue], parent.Title, [parent.CategoryId integerValue]);
}
else
{
NSLog(@"%@(ID: %@) doesn't have a parent",obs.Title, obs.CategoryId);
}
}
}
- (CategoryModel *)searchParentObjectForChild:(CategoryModel *)child
{
for (CategoryModel * obs in self.myJSON.obs)
{
if(obs.CategoryId == child.ParentCategoryId)
{
return obs;
}
}
return nil;
}
注意:如果可能,请不要更改JSON的结构。
如果有人知道如何实现这一点,请告诉我。 欢迎任何建议! 谢谢。
答案 0 :(得分:1)
我假设你有一个这个类的数组,并希望从中构建一个新数组:)
@interface CategoryModel
@property (nonatomic, strong) NSNumber * CategoryId;
@property (nonatomic, strong) NSString * Title;
@property (nonatomic, strong) NSString * Description;
@property (nonatomic, strong) NSNumber * ParentCategoryId;
@end
首先,让我们为每个类别添加另一个属性,当您在app逻辑中使用树时,这将使您的生活更轻松。
@property (nonatomic, strong) NSMutableArray* subCategories;
现在你可能想写这样的东西(请注意,对于大量的类别可能需要很长时间,所以我更喜欢你找到一个已知的算法来构建你的树(可能是AVL树或其他东西))但是对于数百个类别来说,一切都会好起来的。
- (void)findCategoryChildren:(CategoryModel*)category fromArray:(NSMutableArray*)originalCopy currentIndex:(int*)i {
for (int j = 0; j < originalCopy.count; j++) {
CategoryModel* childCategory = originalCopy[j];
if ([childCategory.ParentCategoryId intValue] == [category.CategoryId intValue]) {
if (category.subCategories == nil) {
category.subCategories = [[NSMutableArray alloc] init];
}
[category.subCategories addObject:childCategory];
[originalCopy removeObjectAtIndex:j];
j--;
i--;
// Now find the childs of this child category
[self findCategoryChildren:childCategory fromArray:originalCopy currentIndex:i];
}
}
}
- (NSArray*)sort:(NSArray*)original {
// This is the final array (the tree)
NSMutableArray* result = [[NSMutableArray alloc] init];
// This is a copy of the input to minimize the time of the latter iterations
NSMutableArray* originalCopy = [[NSMutableArray alloc] initWithArray:original];
for (int i = 0; i < originalCopy.count; i++) {
CategoryModel* category = originalCopy[i];
// This is a root category
if (category.ParentCategoryId == nil) {
[result addObject:category];
[originalCopy removeObjectAtIndex:i];
i--;
// Now try to find its children
[self findCategoryChildren:category fromArray:originalCopy currentIndex:&i];
}
}
return result;
}