Problema de lógica [ Resolvido ]

3 respostas
D

É uma ajuda mais na questão de lógica que qqr outra coisa.

Trenho um objeto que me forne todos os itens de uma tree, e eu posso verificar se tem filhos, se é a folha, etc, etc…
E eu preciso ler todos estes itens e montar um json com o seguinte formado:

{
	text:'ItemDaTree', 
	checked: 'true', 
	children:[
				{
					text:'FilhoItemTree1', 
					leaf: 'true'
				},{
					text:'FilhoItemTree2',
						children:[
						{
							text:'FilhoItemTree11', 
							leaf: 'true'
						},{
							text:'FilhoItemTree22',
							children:[
								{
									text:'FilhoItemTree11', 
									leaf: 'true'
								},{
									text:'FilhoItemTree22',
									leaf: 'true'
								}
							]
						}
					]
				}
			]
}

Eu tenho um código que faz uma boa parte do trabalho, mas ele não é 100% eficiente pois ele vai até apenas o 3º nível e eu quero fazer algo que faça isso de uma maneira elegante e automática onde com o uso de alguns loops e uma boa lógica ele vá expandindo os níveis até o fim e verificando as regras para montar o json: isLeaf() , hasChildrenNodes(), etc…

Aqui em cima eu representei o json com apenas 3 níves, mas ele pode ter vários, muitos mesmo!

public String genTreeChilrenToExtjs(){
	  StringBuilder sb = new StringBuilder();
	  Object[] childs;
	  Object roots[] = model.getRoots();
	  sb.append("children:[");
	  for (int i = 0; i < roots.length; i++) {
	      MondrianMember nodeMB = (MondrianMember) roots[i];
	      
	      sb.append("{id: '").append(getIDNodeElementExtjs(roots[i])).append("',text:'")
	      		.append(nodeMB.getMonMember().getName()).append("',")
	      		.append("checked:"+getCheckedToExtjs(roots[i])+",");
	      
		  if(model.hasChildren(nodeMB)){
			  sb.append("children:[");
			  childs = model.getChildren(nodeMB);
			  for(Object ch : childs){
				 sb.append(getAllLevelsChildsToExtjs(ch));
			  }
			  sb.append("]}");
		  }else{
			  sb.append("leaf: true}");
		  }
	  }	  
	  sb.append("]");
	  sb.deleteCharAt(sb.lastIndexOf(","));
	  return sb.toString();
  }
  
  public boolean getCheckedToExtjs(Object n){
	  Element nodeElem = renderNode(null, n, 0);
	  if(nodeElem.getFirstChild().getAttributes().getNamedItem("selected") != null && 
			  !nodeElem.getFirstChild().getAttributes().getNamedItem("selected").equals("") &&
			  		nodeElem.getFirstChild().getAttributes().getNamedItem("selected").toString().contains("true")
			  ){
		  return true;
	  }else{
		  return false;
	  }
  }
  
  public String getIDNodeElementExtjs(Object n){
	  Element nodeElem = renderNode(null, n, 0);
	  return nodeElem.getAttribute("id");
  }
  
  public String getAllLevelsChildsToExtjs(Object n){
	  StringBuilder sb = new StringBuilder();
	  MondrianMember node = (MondrianMember) n;
	  
	  sb.append("{id:'").append(getIDNodeElementExtjs(n)).append("', text:'")
	  		.append(node.getMonMember().getName()).append("',")
	  		.append("checked: ").append(getCheckedToExtjs(n)+",");
	  
	  if(model.hasChildren(node)){
		  Object childs[] = model.getChildren(node);
		  if(childs.length != 0){
			  sb.append("children:[");
			  for(Object ch : childs){
				  
				  sb.append("{id: '").append(getIDNodeElementExtjs(ch)).append("', text:'")
				  		.append(((MondrianMember)ch).getMonMember().getName()).append("',")
				  		.append("checked: "+getCheckedToExtjs(ch)+",");
				  
				  if(model.hasChildren(ch)){
					  while(model.hasChildren(ch)){

						  
						  
						  // CAGADA DETECTED !!
						  // e se sempre tiverem mais e mais filhos?
						  
						  
						  
					  }
				  }else{
					  sb.append("leaf: true");
				  }
				  sb.append("}");
			  }
			  sb.append("]");
		  }else{
			  sb.append("leaf: 'true'");
		  }
	  }else{
		  sb.append("leaf: 'true'");
	  }
	  sb.append("},");
	  return sb.toString();
  }

Agradeço desde já a ajuda de todos!

3 Respostas

M

Usa recursividade.

Você não precisa repetir as instruções para cada nível, mas sim chamar o método que percorre novamente. Algo como um método chamado percorreNos. Esse método receberá um nó da árvore (ele não sabe qual nó é, só sabe que é um nó da árvore). O trabalho dele é verificar se ele é folha ou não. Se ele for folha, ele para as chamadas, se não ele percorre os nós filhos do nó passado como parâmetro e chama novamente percorreNos para cada um dos nós filhos. Como você pode ver, isso continuará até todos os nós folha serem encontrados, sendo que a vantagem do algoritmo é não ter limite de níveis.

Depois de pronto o método percorreNos, basta chamar ele, passando o nó raiz da tree e a mágica acontecerá.

pmlm

Já viste isto?

D
public String getAllLevelsChildsToExtjs(Object n){    
StringBuilder sb = new StringBuilder();    
MondrianMember node = (MondrianMember) n;    
    
sb.append("{id:'").append(getIDNodeElementExtjs(n)).append("', text:'")    
        .append(node.getMonMember().getName()).append("',")    
        .append("checked: ").append(getCheckedToExtjs(n)+",");    
    
if(model.hasChildren(node)){    
  Object childs[] = model.getChildren(node);    
  if(childs.length != 0){    
      sb.append("children:[");    
      for(Object ch : childs){    
              
          sb.append("{id: '").append(getIDNodeElementExtjs(ch)).append("', text:'")    
                .append(((MondrianMember)ch).getMonMember().getName()).append("',")    
                .append("checked: "+getCheckedToExtjs(ch)+",");    
              
          if(model.hasChildren(ch)){    
                    
  
  
                // Resolvido com recursividade:  
                getAllLevelsChildsToExtjs(ch);  
  
  
  
  
          }else{    
              sb.append("leaf: true");    
          }    
          sb.append("}");    
      }    
      sb.append("]");    
  }else{    
      sb.append("leaf: 'true'");    
  }    
}else{    
  sb.append("leaf: 'true'");    
}    
sb.append("},");    
return sb.toString();    
}
Criado 20 de novembro de 2011
Ultima resposta 21 de nov. de 2011
Respostas 3
Participantes 3