Created
July 17, 2014 08:16
-
-
Save Carolusian/3530a9d60cbc25fb1953 to your computer and use it in GitHub Desktop.
List imap mail folders with parent and child relationship
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* List the with parent and child relationship | |
*/ | |
object ImapFolders extends App { | |
val folders = List( | |
"mail201.udomain.com.hk.Winway", | |
"mail201.udomain.com.hk.Winway.Quota", | |
"mail201.udomain.com.hk.Winway.Delivery", | |
"mail201.udomain.com.hk.Winway.PO", | |
"mail201.udomain.com.hk.UA", | |
"mail201.udomain.com.hk.UA.Haha", | |
"mail201.udomain.com.hk.UA.Lala", | |
"mail201.udomain.com.hk.UA.Lala.A", | |
"mail201.udomain.com.hk.UA.Lala.B", | |
"mail201.udomain.com.hk.UA.Vendor", | |
"mail201.udomain.com.hk.UA.Vendor.RSI", | |
"mail201.udomain.com.hk.UA.Vendor.American Phil", | |
"mail201.udomain.com.hk.UA.Vendor.American Phil.PO", | |
"mail201.udomain.com.hk.UA.Vendor.SCI", | |
"mail201.udomain.com.hk.UA.Color", | |
"mail201.udomain.com.hk.Excellent", | |
"mail201.udomain.com.hk.Excellent.PO", | |
"mail201.udomain.com.hk.Excellent.Quote", | |
"mail201.udomain.com.hk.Maker", | |
"mail201.udomain.com.hk.Maker.Maker Factory", | |
"mail201.udomain.com.hk.Champion", | |
"mail201.udomain.com.hk.Champion.Order", | |
"mail201.udomain.com.hk.Champion.Quote", | |
"mail201.udomain.com.hk.Champion.Delivery", | |
"mail201.udomain.com.hk.TAL", | |
"mail201.udomain.com.hk.TAL.Order", | |
"mail201.udomain.com.hk.TAL.Quote", | |
"mail201.udomain.com.hk.TAL.Account", | |
"mail201.udomain.com.hk.GPSS", | |
"mail201.udomain.com.hk.Sent Messages", | |
"mail201.udomain.com.hk.HSBC", | |
"mail201.udomain.com.hk.Drafts", | |
"mail201.udomain.com.hk.Other Factory", | |
"mail201.udomain.com.hk.Deleted Message", | |
"Outbox", | |
"Spam", | |
"Draft", | |
"Trash", | |
"OldInbox", | |
"INBOX" | |
) | |
//!--NOTE-- | |
//The gist divide the following steps into two steps for better illustration | |
//Actually, step 1 and 2 can be merged together... | |
// Step 1: | |
// Find grouped folders foreach elemented | |
// If the size of a group is one, this means its group member is itself | |
val groupedFolders = | |
folders map (x => findGroup(x, folders)) | |
//groups which have children | |
val groupsWithChildren = groupedFolders filter (_.length > 1) | |
// Check whether any group it is a child of other groups. | |
// If yes, remove it | |
val uniqueGroupedFolders = groupedFolders filter { x => | |
//Loop though all groupsWithChildren | |
//Check if any of them contains x, | |
// If x is contained in subgroups, | |
// need to remove x in this group to avoid duplication | |
if(inSubgroup(x, groupsWithChildren)) false | |
else true | |
} | |
uniqueGroupedFolders foreach (println) | |
println(uniqueGroupedFolders(6)) | |
println("-------------------------------") | |
// Step 2: | |
// For each group whose member size is larger than 3, | |
// we need to do similar stuffs recursively since subgroup may exist | |
val groupedResult = uniqueGroupedFolders map { grp => | |
if(grp.length >= 3) | |
divideSubgroup(grp, 0) | |
else | |
grp | |
} | |
groupedResult foreach println | |
def divideSubgroup(group: List[String], level:Int):List[Any] = { | |
//Remeber that the first elem is parent, So start with the second elem | |
val subGroup = group.tail | |
val grpedFolders = subGroup map (x => findGroup(x, subGroup)) | |
val grpsWithChildren = grpedFolders filter (_.length > 1) | |
val uniqueGrpedFolders = grpedFolders filter { x => | |
if(inSubgroup(x, grpsWithChildren)) false | |
else true | |
} | |
//If the group size is 1, means no subgroup | |
val children = uniqueGrpedFolders filter (_.length == 1) | |
//If the group size > 2, means it is a potential subgroup | |
val potentialSubgroups = uniqueGrpedFolders filter (_.length > 1) | |
val result:List[Any] = (group.head :: children.map(_.head)) | |
if(!potentialSubgroups.isEmpty) | |
potentialSubgroups.foldLeft(result) { (r, sub) => | |
r ::: List(divideSubgroup(sub, level + 1)) | |
} | |
else | |
result | |
} | |
def inSubgroup(elem:List[String], haystack:List[List[String]]):Boolean = { | |
for(compare <- haystack) { | |
if(compare.length > elem.length | |
&& compare.toSet.intersect(elem.toSet) == elem.toSet) | |
return true | |
} | |
return false | |
} | |
def findGroup(elem: String, haystack: List[String]):List[String] = { | |
//Find all elements startWith "elem." in "haystack" | |
//e.g. if "elem" is "mail201.udomain.com.hk.TAL", | |
//then mail201.udomain.com.hk.TAL.Order and similar items should be | |
//returned | |
return elem :: haystack.filter(_.startsWith(s"$elem.")) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment