+ Start a Discussion
THBrunoTHBruno 

Multidimensional lists

Hi all,

 

My first post on the board!

 

I'm looking into the possibility to print such a hierarchy on a visualforce page:

 

-Object 1
    * Object 3
    * Object 4
        • Object 5

               # Object 7
        • Object 6

 

Objects are all of the same type, and relations between them are also stored in the database.

 

What I did so far is some looping in order to find objects related to each other.

The problem comes up when I want to add the elements the a List.

My idea was to have a List within a List within a List within a List... and loop over this on my page.

 

But with this part I'm stuck. How adding them to a list?

Purpose would be to have it structured with a parent object next to a list of child objects:

 

Object 1, List{
    Object 3, null (no list, because no child elements)
    Object 4, List {
            Object 5, List {
                    Object 7, null (no list, because no child elements)
                    }
            Object 6, null (no list, because no child elements)
            }
        }

 

Is this possible with lists?

 

Anyone did something similar so far?

 

Thanks for helping me out!

 

Best Answer chosen by Admin (Salesforce Developers) 
Sean TanSean Tan

The code I posted should theoretically be able to handle that type of hiearchy (it shouldn't be infinitely looping, two loops were used, one to build the big list of items with their Id and the second to remap which one belongs where).

All Answers

max_overloadmax_overload

I would probably use a nested map structure for this type of use case. I'm not sure I completely understand your use-case fully, but here goes:

 

1) You have a hierarchy of objects

2) Each object is of a different type?

3) Each object *should* have its hierarchical parent_id imprinted upon it

4) You would like to organize a data structure in Apex during runtime to show this hierarchical relationship

 

Map<String(hierarchyId),Map<Object(Object1),Map<Object(Object3,4,6),Map<Object(Object5),List<Object>(Object7's)>>>> hierarchyMap;

 You can extend the Map<> structure as deep as you need to, always finishing at your deepest hierarchical object. So, when you want to get your deepest entity, your just chaining through get().get().get().get() to dig through the Map. For objects without children for that particular level, you'll have to put in null placeholders.

 

To safely traverse the Map, I would build a utility method. Pass the method the level of hierarchy your expected the value your are searching for to be and handle exceptions within this helper method gracefully.

 

Another way to do this with Map structures but more effectively would be to utilize a Wrapper Class to encapsulate hierarchy placement of each object within a shared structure, and then store collections of those wrappers beneath the hierarchy level.

Map<String(level),List<WrapperObject>(each wrapper describes itself - ie: who its parent is supposed to be etc.)

 

THBrunoTHBruno

1) You have a hierarchy of objects

yes

2) Each object is of a different type?

no, all of the same type (Object__C to be precise :-) )

3) Each object *should* have its hierarchical parent_id imprinted upon it

not necessary, I think that with the solution you propose, I'm perfectly able to find the parent, because it is a pair (parent object + map of child objects). Correct?

4) You would like to organize a data structure in Apex during runtime to show this hierarchical relationship

Yes, print out the different levels on a page, somewhat like the example in the first post

max_overloadmax_overload

Got it! I'm totally following you now.

 

Yes, given the structure I presented (parent obj + map of children +map of children + map of children +child) you should be able to organize your singular object type quite well. Even without the Parent_Id embedded on each record. As long as you know how they should be organized at runtime.

THBrunoTHBruno

In fact, what would be the advantage to use a Map for this?

Is is not possible with a List or a Set?

Sean TanSean Tan

I think you could do this with a custom class combined with a single list object. Something like this may work?

 

public with sharing class MyClass
{
	public CustomAccount[] accountList { get;set; }

	public MyClass()
	{
	}
	
	public void populateList()
	{
		accountList = new CustomAccount[]{};
		
		Map<Id, CustomAccount> customAccountMap = new Map<Id, CustomAccount>{};
		
		for (Account a : [select Id, Name, ParentId from Account where Name = 'blah'])
		{
			customAccountMap.put(a.Id, new CustomAccount(a));
		}				
		
		//Second loop is to re-map all the parent and children
		for (CustomAccount a : customAccountMap.values())
		{
			if (a.ParentId == null)
			{
				accountList.add(a);
			}
			else
			{
				CustomAccount parent = customAccountMap.get(a.ParentId);
				
				if (parent != null)
				{
					parent.childAccountList.add(a);
				}
			}
		}	
	}
	
	class CustomAccount
	{
		//Have properties here that you want to expose on the page
		public String name { get;set; }
		public Id parentId;
		public CustomAccount[] childAccountList;
	
		public CustomAccount(Account a)
		{
			this.name = a.Name;
			this.parentId = a.ParentId;
			childAccountList = new CustomAccount[]{};
		}
	}
}

 

 

 

THBrunoTHBruno

In fact, the amount of levels in the hierarchy will not be fixed upfront. So the looping has to be infinite in order to make sure he goes to the bottom of the structure

 

Sean TanSean Tan

The code I posted should theoretically be able to handle that type of hiearchy (it shouldn't be infinitely looping, two loops were used, one to build the big list of items with their Id and the second to remap which one belongs where).

This was selected as the best answer