将 NSMutableArray 排序为线程注释
Sort NSMutableArray as threaded comments
我正在为网站开发一个 iOS 应用程序,它使用 disqus 评论系统。
所以我正在尝试添加功能以从此应用程序添加评论。
我的问题是我不知道如何保持线程结构,例如:
- Comment 1
- Child 1.1
- Child 1.1.1
- Child 1.1.2
- Child 1.2
- Child 1.2.1
- Comment 2
- Child 2.1
我在 Java 这里找到了解决方案 java solution
差不多可以了,但是有个大问题。
它使结构像这样:
- Comment 1
- Child 1.1
- Child 1.2
- Child 1.2.1
- Child 1.1.1
- Child 1.1.2
- Comment 2
- Child 2.1
破坏了parents和children的关系
当我添加一个新的child时,它只知道它的parent有多少child人,也就是说这个child有多少兄弟。
但是没有资料说这个child的兄弟还有children,也就是说我加一个新的child的时候并不知道他有侄子。
[threaded insertObject:child atIndex:i+[parent childCount]];
请帮帮我,我真的卡住了。
这里是link,用于测试项目link
下面是 objective-c
中对数组进行排序的代码
+ (NSMutableArray *)makeThreadedCommentsOutOf:(NSMutableArray *)comments{
NSMutableArray *threaded = [[NSMutableArray alloc] initWithCapacity:0];
//An array used to hold processed comments which should be removed at the end of the cycle
NSMutableArray *removeComments = [[NSMutableArray alloc] initWithCapacity:0];
//get the root comments first (comments with no parent)
for(int i = 0; i < [comments count]; i++){
Comment *comment = [comments objectAtIndex:i];
if([[comment parentId] isEqual:[NSNull null]]){
comment.commentDepth = 0;//A property of Comment to hold its depth
comment.childCount = 0;
[threaded addObject:comment];
[removeComments addObject:comment];
}
}
if([removeComments count] > 0){
//clear processed comments
[comments removeObjectsInArray:removeComments];
[removeComments removeAllObjects];
}
int depth = 0;
//get the child comments up to a max depth of 10
while([comments count] > 0 && depth <= 10){
depth++;
for(int j = 0; j< [comments count]; j++){
Comment *child = [comments objectAtIndex:j];
//check root comments for match
for(int i = 0; i < [threaded count]; i++){
Comment *parent = [threaded objectAtIndex:i];
if([[parent commentId] isEqualToString:[child parentId]]){
[parent setChildCount:[parent childCount]+1 ];
[child setCommentDepth:depth+[parent commentDepth]];
[threaded insertObject:child atIndex:i+[parent childCount]];
[removeComments addObject:child];
continue;
//break;
}
}
}
if([removeComments count] > 0){
//clear processed comments
[comments removeObjectsInArray:removeComments];
[removeComments removeAllObjects];
}
}
return threaded;
}
虽然你没有这么说,但你的数组中的评论似乎已经按时间顺序排列了;那就是 children 发生在他们的 parents 和他们之前的任何兄弟姐妹之后。
您的问题是,评论不会紧跟在其前一个兄弟及其所有 children 之后,或者如果它是第一个 child,则不会紧跟在其 parent 之后。
你也没有说评论是否知道他们child人的commentID
,但是你说他们知道他们parent的commentID
。
如果以上任何一条是错误的,那么其余答案可能对您没有帮助。假设它是正确的,请考虑以下粗略算法:
- 创建一个空数组来保存所有根评论,那些没有 parents.
- 创建一个空字典以将 parent
commentID
映射到评论数组中的 child 索引数组。
- 逐一检查您的评论数组,依次检查每条评论。如果评论没有 parent ,请将其添加到您的根评论数组中。如果它有一个 parent 将评论的索引添加到您的字典中,它将 parent
commentID
映射到 child 索引的数组。
使用这两种数据结构,您可以轻松地按照您希望的顺序遍历您的评论。您遍历根注释数组,并且对于每个注释,您通过遍历在字典中找到的 child 索引数组来遍历其 children。以此类推,递归。
如果您想要一个 "sorted" 数组,您可以使用上述递归算法创建它,无需尝试计算在现有可变数组中插入注释的位置 - 您发现这是一项具有挑战性的任务 -评论将按正确的顺序添加。
HTH
附录:对评论的回应
递归 是编程中的一个基本概念。在pseudo-code大纲中,上面描述的算法是:
visitAllDescendants(comment - the parent comment
allComments - indexed collection of all comments
parentToChildren - map from parentID to child comment indexes
)
{
do something with comment - do whatever you want with the parent
for every childIndex in order from parentToChildren[comment] do
visitAllDescendants(allComments[childIndex], allComments, parentToChildren) - recursively process children
}
你会为你的每个根调用它。
如果您的 "do something with comment" 是将其添加到有序集合中,那么该算法将按照您想要的顺序生成评论集合。
我正在为网站开发一个 iOS 应用程序,它使用 disqus 评论系统。 所以我正在尝试添加功能以从此应用程序添加评论。
我的问题是我不知道如何保持线程结构,例如:
- Comment 1
- Child 1.1
- Child 1.1.1
- Child 1.1.2
- Child 1.2
- Child 1.2.1
- Comment 2
- Child 2.1
我在 Java 这里找到了解决方案 java solution
差不多可以了,但是有个大问题。 它使结构像这样:
- Comment 1
- Child 1.1
- Child 1.2
- Child 1.2.1
- Child 1.1.1
- Child 1.1.2
- Comment 2
- Child 2.1
破坏了parents和children的关系
当我添加一个新的child时,它只知道它的parent有多少child人,也就是说这个child有多少兄弟。
但是没有资料说这个child的兄弟还有children,也就是说我加一个新的child的时候并不知道他有侄子。
[threaded insertObject:child atIndex:i+[parent childCount]];
请帮帮我,我真的卡住了。
这里是link,用于测试项目link
下面是 objective-c
中对数组进行排序的代码+ (NSMutableArray *)makeThreadedCommentsOutOf:(NSMutableArray *)comments{
NSMutableArray *threaded = [[NSMutableArray alloc] initWithCapacity:0];
//An array used to hold processed comments which should be removed at the end of the cycle
NSMutableArray *removeComments = [[NSMutableArray alloc] initWithCapacity:0];
//get the root comments first (comments with no parent)
for(int i = 0; i < [comments count]; i++){
Comment *comment = [comments objectAtIndex:i];
if([[comment parentId] isEqual:[NSNull null]]){
comment.commentDepth = 0;//A property of Comment to hold its depth
comment.childCount = 0;
[threaded addObject:comment];
[removeComments addObject:comment];
}
}
if([removeComments count] > 0){
//clear processed comments
[comments removeObjectsInArray:removeComments];
[removeComments removeAllObjects];
}
int depth = 0;
//get the child comments up to a max depth of 10
while([comments count] > 0 && depth <= 10){
depth++;
for(int j = 0; j< [comments count]; j++){
Comment *child = [comments objectAtIndex:j];
//check root comments for match
for(int i = 0; i < [threaded count]; i++){
Comment *parent = [threaded objectAtIndex:i];
if([[parent commentId] isEqualToString:[child parentId]]){
[parent setChildCount:[parent childCount]+1 ];
[child setCommentDepth:depth+[parent commentDepth]];
[threaded insertObject:child atIndex:i+[parent childCount]];
[removeComments addObject:child];
continue;
//break;
}
}
}
if([removeComments count] > 0){
//clear processed comments
[comments removeObjectsInArray:removeComments];
[removeComments removeAllObjects];
}
}
return threaded;
}
虽然你没有这么说,但你的数组中的评论似乎已经按时间顺序排列了;那就是 children 发生在他们的 parents 和他们之前的任何兄弟姐妹之后。
您的问题是,评论不会紧跟在其前一个兄弟及其所有 children 之后,或者如果它是第一个 child,则不会紧跟在其 parent 之后。
你也没有说评论是否知道他们child人的commentID
,但是你说他们知道他们parent的commentID
。
如果以上任何一条是错误的,那么其余答案可能对您没有帮助。假设它是正确的,请考虑以下粗略算法:
- 创建一个空数组来保存所有根评论,那些没有 parents.
- 创建一个空字典以将 parent
commentID
映射到评论数组中的 child 索引数组。 - 逐一检查您的评论数组,依次检查每条评论。如果评论没有 parent ,请将其添加到您的根评论数组中。如果它有一个 parent 将评论的索引添加到您的字典中,它将 parent
commentID
映射到 child 索引的数组。
使用这两种数据结构,您可以轻松地按照您希望的顺序遍历您的评论。您遍历根注释数组,并且对于每个注释,您通过遍历在字典中找到的 child 索引数组来遍历其 children。以此类推,递归。
如果您想要一个 "sorted" 数组,您可以使用上述递归算法创建它,无需尝试计算在现有可变数组中插入注释的位置 - 您发现这是一项具有挑战性的任务 -评论将按正确的顺序添加。
HTH
附录:对评论的回应
递归 是编程中的一个基本概念。在pseudo-code大纲中,上面描述的算法是:
visitAllDescendants(comment - the parent comment
allComments - indexed collection of all comments
parentToChildren - map from parentID to child comment indexes
)
{
do something with comment - do whatever you want with the parent
for every childIndex in order from parentToChildren[comment] do
visitAllDescendants(allComments[childIndex], allComments, parentToChildren) - recursively process children
}
你会为你的每个根调用它。
如果您的 "do something with comment" 是将其添加到有序集合中,那么该算法将按照您想要的顺序生成评论集合。