Generate a new JSON by manipulating data from another JSON

Asked

Viewed 145 times

2

I was participating in an internship test and I was proposed the following problem:

I would have to read the JSON below:

[ 
{ "nome":"Jabba, the Hutt", "jedi":false, "sistemas":[ "Tatooine" ] },
{ "nome":"Chewbacca", "jedi":false, "sistemas":[ "Kashyyk" ] },
{ "nome":"Han", "jedi":false, "sistemas":[ "Tatooine", "Coruscant" ] },
{ "nome":"Leia", "jedi":true, "sistemas":[ "Alderaan", "Endor" ] },
{ "nome":"Luke", "jedi":true, "sistemas":[ "Tatooine", "Dagobah" ] },
{ "nome":"Yoda", "jedi":true, "sistemas":[ "Kashyyk", "Dagobah" ] },
{ "nome":"Obi-Wan", "jedi":true, "sistemas":[ "Coruscant", "Mustaphar" ] },
{ "nome":"Darth Vader", "jedi":false, "sistemas":[ "Tatooine", "Mustaphar" ] }]

And you’d have to create a new JSON that would look something like this:

[{"nome": Darth Vader, "contato":["Luke", "Leia" ....]},{}]

It would be a JSON that would have in each field the name of the character and an array that would be the contacts.

Now the condition for a character to enter the contact array of another character is:

  • that this character is not the same character from the name field

  • 2 characters can contact each other if they are both "jedi":true OR if they have any system in common. For example the Jabba, the Hutt will be Han’s contact because both have Tatooine in their arrays in the field systems.

This is my code:

var v = [ 
{ "nome":"Jabba, the Hutt", "jedi":false, "sistemas":[ "Tatooine" ] },
{ "nome":"Chewbacca", "jedi":false, "sistemas":[ "Kashyyk" ] },
{ "nome":"Han", "jedi":false, "sistemas":[ "Tatooine", "Coruscant" ] },
{ "nome":"Leia", "jedi":true, "sistemas":[ "Alderaan", "Endor" ] },
{ "nome":"Luke", "jedi":true, "sistemas":[ "Tatooine", "Dagobah" ] },
{ "nome":"Yoda", "jedi":true, "sistemas":[ "Kashyyk", "Dagobah" ] },
{ "nome":"Obi-Wan", "jedi":true, "sistemas":[ "Coruscant", "Mustaphar" ] },
{ "nome":"Darth Vader", "jedi":false, "sistemas":[ "Tatooine", "Mustaphar" ] }];

function verificaSist(){
    var verifica = false;
    for(var i in arguments[0]){
        for(var b in arguments[1]){
            if(arguments[0][i]===arguments[1][b]){
                verifica = true;
                break;      
            }   
        }
        if(verifica == true){
            break;
        }
    }
    if(verifica == true){
        return true;
    }
    else{
        return false;
    }

  }

function criaAgenda(v){
  var agenda=[];
  var contato = []
  for(var personagem1 of v){
    for(var personagem2 of v){
        var sist = [personagem1.sistemas, personagem2.sistemas];
        var d = verificaSist.apply(null,sist);

        if(((personagem1.jedi == true && personagem2.jedi==true)|| d == true) && personagem1.nome !== personagem2.nome){
            contato.push(personagem2.nome);
        }
    }
    agenda.push({"nome":personagem1.nome, "contato":contato=[]});

  }
  return JSON.stringify(agenda);
}
console.log(criaAgenda(v));

The problem as far as I’m concerned is this if:

if(((personagem1.jedi == true && personagem2.jedi==true)|| d == true) && personagem1.nome !== personagem2.nome)

I just can’t think of anything better.

  • "Read" has no relation to "Darth Vader": both are not "Jedi" and have no common systems.

1 answer

1


The code itself would work correctly, except for array placement contato in the wrong place. Correct would be to reset this array every time around the first for in function criaAgenda:

for(var personagem1 of v){
   var contato = [];
   for(var personagem2 of v){
      ...
   }
}

And in the agenda.push inform only the array:

agenda.push({"nome":personagem1.nome, "contato":contato});

Another thing are dispensable codes in function verificaSist(). Instead of doing breaks, just return true when something matches, otherwise return false, without using the control variable verifica.

By doing the return in the function, the loop is already suspended without needing to break. Other things that can dry the code is to check if the variable is true only with the variable itself, without == true, for example:

if(d == true) is the same as if(d) and if(d == false) is the same as if(!d)

See how the function would look verificaSist() without excess and compare to your original:

function verificaSist(){
   for(var i in arguments[0]){
      for(var b in arguments[1]){
         if(arguments[0][i]===arguments[1][b]) return true;
      }
   }
   return false;
}

A lot simpler, no?!

Code in operation:

var v = [ 
{ "nome":"Jabba, the Hutt",   "jedi":false, "sistemas":[ "Tatooine" ] },
{ "nome":"Chewbacca",         "jedi":false, "sistemas":[ "Kashyyk" ] },
{ "nome":"Han",               "jedi":false, "sistemas":[ "Tatooine", "Coruscant" ] },
{ "nome":"Leia",              "jedi":true,  "sistemas":[ "Alderaan", "Endor" ] },
{ "nome":"Luke",              "jedi":true,  "sistemas":[ "Tatooine", "Dagobah" ] },
{ "nome":"Yoda",              "jedi":true,  "sistemas":[ "Kashyyk", "Dagobah" ] },
{ "nome":"Obi-Wan",           "jedi":true,  "sistemas":[ "Coruscant", "Mustaphar" ] },
{ "nome":"Darth Vader",       "jedi":false, "sistemas":[ "Tatooine", "Mustaphar" ] }];

function verificaSist(){
   for(var i in arguments[0]){
      for(var b in arguments[1]){
         if(arguments[0][i]===arguments[1][b]) return true;
      }
   }
   return false;
}

function criaAgenda(v){
  var agenda=[];
  
  for(var personagem1 of v){
    var contato = [];
    for(var personagem2 of v){
        var sist = [personagem1.sistemas, personagem2.sistemas];
        var d = verificaSist.apply(null,sist);

        if( (personagem1.jedi && personagem2.jedi || d) && personagem1.nome !== personagem2.nome){
            contato.push(personagem2.nome);
        }
    }

    agenda.push({"nome":personagem1.nome, "contato":contato});

  }
  return JSON.stringify(agenda);
}

console.log(JSON.parse(criaAgenda(v)));

Browser other questions tagged

You are not signed in. Login or sign up in order to post.