Problem with simple Json Javascript sorting script

Asked

Viewed 87 times

0

I am learning Javascript and am creating a script that needs to put a Json file in alphabetical order and print on the screen if you have repeated item and if it exists show which.

I have looked at several questions and so far I could not find a conclusion, if someone help me I will be very grateful

This is my HTML script:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div class="container">
        <ul id="data"></ul>
        <div id="app"></div>"
        <button  onClick="console.log(dados, uniqNames)"> Rotate </button>
    </div>
    <script type="text/javascript">


const dados = {
"alimentos": 
    {

      "carne": "carne",
      "arroz": "feijão",
      
},
"bebidas": 
    {

      "agua": "gelada",
      "leite": "nescau",
      
},
    
    }

    // Pega os nome 
    const names = dados.alimentos.map( identificar => identificar.CLIENT_ID )
    const names = dados.bebidas.map( bebidas => bebidas.CLIENT_ID )
    

    // Filtrar nomes repetidos
    const uniqNames = names.filter((name, index, self) => self.indexOf(name) === index)
    
    //Coloca em ordem alfabetica 
    uniqNames.sort(function (a, b) {
    return (a.nome > b.nome) ? 1 : ((b.nome > a.nome) ? -1 : 0);
        
});

    //Passa os nomes verificados 
    let resultados = [];
    uniqNames.forEach( uName => {
    names.forEach( name => {
        if (name == uName) {
            resultados[uName] = (resultados[uName] > 0 ? resultados[uName] : 0)  + 1
        }
        
    })
    
})
    console.log(dados, uniqNames)
    </script>
    
</body>
</html>

the expected result is put Json in alphabetical order translation car:cars milk:milk

translation 2 love:love car:cars

(Print message that is repeated) message: car:car is repeated

<script>
const dados = {
"tradução": 
    {

      "car": "carros",
      "leite": "milk",
      
},
"tradução_2": 
    {
      "car": "carros",
      "amor": "love",
      
},
    
    }

    // Pega os nome 
    const names = dados.tradução.map( tradução => tradução.CLIENT_ID )

    // Filtrar nomes repetidos
    const uniqNames = names.filter((name, index, self) => self.indexOf(name) === index)
    
    //Coloca em ordem alfabetica 
    uniqNames.sort(function (a, b) {
    return (a.nome > b.nome) ? 1 : ((b.nome > a.nome) ? -1 : 0);
        
});

    //Passa os nomes verificados 
    let resultados = [];
    uniqNames.forEach( uName => {
    names.forEach( name => {
        if (name == uName) {
            resultados[uName] = (resultados[uName] > 0 ? resultados[uName] : 0)  + 1
        }
        
    })
    
})
    console.log(dados, uniqNames)
    </scrtipt>

  • The "Json file" you want to sort is the data variable? Why is it in this format? It would not be better to do so: data ={"food": ["meat", "rice", "beans"], "drinks": ["water", "milk"]}

  • yes this way I did and it worked, however I need to do in a specific Json that is in this format

  • 1

    The shape that is in the question makes no sense. An object has key and value. The way you put it is key "meat", value "meat", then key "rice", value "beans". Agree that makes no sense? Why do you say it needs to be like this? Another error in your code is just below, you are declaring names twice and trying to access a property that doesn’t exist: CLIENT_ID

  • 1

    this Json is a huge list I just put this example by format, because it is a translation Json so for example it ta key"car": value "car" I need to print the key and the value not only the value, and relation to Names I fix but it only takes the "food" would like to read tbm "drink" that’s the doubt tbm

  • 1

    What is the expected result? Please create a [mcve], you don’t need all this code to demonstrate the problem. For example, the <head> HTML does not influence your question at all...

  • There is no way to sort object keys, IE, it is not possible to do what you want and keep the structure of this json.

Show 1 more comment

1 answer

1


Hello!

I will try to help you. Some important points, first of all:

  • A JSON has no order. It is an associative structure (dictionary or hash-table), where the items are identified by "keys", so at the bottom, if I assemble a structure...
{
    a: 1,
    b: 2,
}

...a doesn’t come before b and b doesn’t come before a. This is an internal JS decision, and if you go through the keys and they appear in that order, treat it as a coincidence and not an obligation.

  • Derived from the above point you may notice that then it is not possible order a JSON. What you want to do is walk it (Traverse) in a specific order.

  • It is also interesting to note that JSON is a tree structure. This means that there is a root (in your example, dados) and each element has several children, i.e., it is one hierarchy. This means that when ordering you need to make a decision if you show the items by depth or by width. I’ll assume what you need is by depth, which is the most common.

// exemplo
{
  "1": {
    "1.1": {
      "1.1.1": {},
      "1.1.2": {},
    },
    "1.2": {
      "1.2.1": {},
      "1.2.2": {},
    },
  "2": {
    "2.1": {
      "2.1.1": {},
    },
    "2.2": {
      "2.2.1": {}
    }
  } 
}


Depth order: 1, 1.1, 1.1.1, 1.1.2, 1.2, 1.2.1, 1.2.2, 2, 2.1, 2.1.1, 2.2, 2.2.1 Order by width: 1, 2, 1.1, 1.2, 2.1, 2.2, 1.1.1, 1.1.2, 1.2.1, 1.2.2, 2.1.1. , 2.2.1

Note how in the order by profunity first we go down on the tree, while in width we look at the brothers first.


Put these points, what you need to do at a high level is:

  • Recover the keys you want to browse,
  • Sort these keys,
  • Display them (or, if you prefer, store them in an array/array, which has sorting).
  • Scroll through children - at this point, it’s important to see if the item has children.

Then see:

const dados = {
  "alimentos": {
    "carne": "carne",
    "arroz": "feijão",    
  },
  "bebidas": {
    "agua": "gelada",
    "leite": "nescau",      
  },
};

/** Percorre por profundidade e imprime o resultado */
function depthFirstTraversal(data) {
  // recupera as chaves do objeto no nível atual
  const chaves = Object.keys(data);
  // ordena as chaves
  const chavesOrdenadas = chaves.sort();
   
  // percorre as chaves
  for (const chave of chavesOrdenadas) {
    // imprime a chave atual
    console.log(chave); 
    // recupera os filhos desta
    const filhos = data[chave];
    // verifica se o item atual tem filhos ou se já é a tradução
    if (typeof filhos == "object") {
      // desce percorrendo os filhos o item atual
      depthFirstTraversal(filhos);
    }
  }
}

// executa
depthFirstTraversal(dados);
  • 1

    Thank you very much for your answer. But that way he just printed the keys "food and drink" my doubt is how to open and sort what is inside those keys Thanks for sharing the knowledge that I learned now will be very useful

  • @Glen has an error in the code, it is fixed. I used "children" before declaring. Javascript, a delight of language. :(

  • worked out that way, now the only doubt is how to print only the repeated

Browser other questions tagged

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