Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Transformar um Array em Object - JavaScript

Salve salve a todos, tenho este array de strings:

const produtos = ["camisa-PP", 
  "camisa-M", 
  "camisa-G", 
  "camisa-GG", 
  "camisa-GG", 
  "camiseta-PP", 
  "camiseta-G", 
  "cueca-M", 
  "blusa-XG", 
  "blusa-XG", 
  "blusa-XG", 
  "blusa-P"];

E preciso convertê-lo para o seguinte formato:

{ 
  "camisa": { 
    "PP": 1, 
    "M": 1, 
    "G": 1, 
    "GG": 2 
  }, 
  "camiseta": { 
    "PP": 1, 
    "G": 1 
  }, 
  "cueca": { 
    "M": 1 
  }, 
  "blusa": { 
    "XG": 3, 
    "P": 1 
  }
}

Até agora obtive sucesso em utilizar o split( ) para substituir os separadores de traço ( - ) , para dois pontos ( : ) , e em convertê-lo para um JSON, da seguinte maneira:

var json = produtos.map(elements => JSON.parse(`{"${elements.split('-').join('":"')}"}`));
console.log(json);

Contudo emperrei ao encontrar solução para agrupar os items repetidos e contabilizar a quantidade dos tamanhos disponíveis.

Alguém poderia me dar uma luz de como fazer isto ?

Muito obrigado !

3 respostas

Erick,

assim, acho que exclui os repetidos antes:

<script>
var produtos = ["camisa-PP", 
"camisa-M", 
"camisa-G", 
"camisa-GG", 
"camisa-GG", 
"camiseta-PP", 
"camiseta-G", 
"cueca-M", 
"blusa-XG", 
"blusa-XG", 
"blusa-XG", 
"blusa-P"];


function uniqBy(a, key) {
    var visto = {};
    return a.filter(function(item) {
        var k = key(item);
        return visto.hasOwnProperty(k) ? false : (visto[k] = true);
    })
}

produtos = uniqBy(produtos, JSON.stringify);
console.log(produtos);


var json = produtos.map(elements => JSON.parse(`{"${elements.split('-').join('":"')}"}`));
console.log(json);

</script>

Akashi,

Realmente excluir funciona, mas não é o que preciso como solução. Vou pegar trecho de cada código para comparação pra tentar ficar mais claro:

Aqui temos o Array, e temos camisas de tamanho, PP, M, G e no caso o tamanho GG aparece duas vezes, portanto ao invés de excluir o valor repetido, gostaria de registrar que "camisa no tamanho GG são 2".

const produtos = ["camisa-PP", 
  "camisa-M", 
  "camisa-G", 
  "camisa-GG", 
  "camisa-GG"];

Já aqui tenho um Object com um item camisa que agrupa os tamanhos PP, M, G e GG e após seus respectivos valores, ficando assim, PP: 1, M: 1, G:1 e GG: 2.

{ 
  "camisa": { 
    "PP": 1, 
    "M": 1, 
    "G": 1, 
    "GG": 2 
  }
}

Eu fiz alguns testes hoje pela manhã e cheguei nesse código que está me abrindo um caminho:

let result = json.reduce(function(r, a) {
    r[a.camisa] = r[a.camisa] || [];
    r[a.camisa].push(a.camisa);
    return r;
    }, Object.create(json));

console.log(result);

Ele me retorna o seguinte resultado:

Array {
  PP: [ 'PP' ],
  M: [ 'M' ],
  G: [ 'G' ],
  GG: [ 'GG', 'GG' ],
  undefined: [ undefined, undefined, undefined, undefined, undefined, undefined ]
}

Ele já agrupa os valores repetidos do tamanho GG. Agradeço muito sua ajuda, mas se ainda tiver alguma sugestão, lhe agradeço ainda mais, Hahahaha.

solução!

Depois de algum tempo encontrei a solução com a ajuda do pessoal da comunidade do Stackoverflo, estarei postando a resolução aqui para ajudas posteriores:

Créditos ao Luiz Felipe

Há de se mencionar, antes de tudo, que não há necessidade de utilizar JSON.parse aí (montando a string do JSON de forma literal), já que esse é um meio menos performático e mais suscetível a eventuais erros. Ao invés disso, você pode utilizar a própria linguagem para manipular as estruturas de dados diretamente, sem a necessidade de criar strings em JSON.

Tendo isso em vista, há de se entender que o resultado esperado é um objeto e a entrada, um array. Desse modo, você precisa pensar em um jeito de, a partir de um objeto vazio inicial, incrementar os valores conforme se percorre o array. Um exemplo de implementação seria esta:

function groupProducts(arr) {
  // Nosso objeto (vazio) inicial:
  const result = {};

  for (const item of arr) {
    // Cada `item` é algo como "camisa-PP".
    // Portanto, podemos utilizar o método `split` para separá-lo em nome e tamanho:
    const [name, size] = item.split('-');

    // No caso do `name` da iteração atual ainda não ter sido criado:
    if (!result[name]) {
      result[name] = {};
    }

    result[name][size] = (result[name][size] || 0) + 1;
  }

  return result;
}

console.log(
  groupProducts([
    "camisa-PP", "camisa-M", "camisa-G",
    "camisa-GG", "camisa-GG", "camiseta-PP",
    "camiseta-G", "cueca-M", "blusa-XG",
    "blusa-XG", "blusa-XG", "blusa-P"
  ])
);

Basicamente, cada elemento do array original é sempre uma string como "camisa-PP". Separando-a pelo hífen (-), obtemos o nome do produto e o respectivo tamanho. Isso é feito em cada iteração do laço de repetição.

Em posse dessas informações, criamos um objeto para cada produto e um sub objeto para cada tamanho. Utilizamos o operador ||, ali fazendo avaliação de curto-circuito, para criar o valor inicial padrão zero, no caso do tamanho ainda não tiver sido contabilizado.