Como comparar a matriz de formato JSON VALUE e KEY para criar uma nova matriz? em Angular 5

10

Aqui está o meu primeiro formato de matriz JSON:

this.columnNames = [
  {field : "Name"},
  {field : "Address"},
  {field : "Age"}
];

Aqui está o meu primeiro formato de matriz JSON:

this.rowData = [
  {Name : "Praveen",Address : "aiff",Age : "12",w :  "1",e :  "8"},
  {Name : "Akashay",Address : "xvn",Age : "15",w :  "2",e :  "7"},
  {Name : "Bala",Address : "hjk",Age : "16",w :  "3",e :  "6"}, 
  {Name : "Charu",Address : "sss",Age : "17",w :  "4",e :  "5"},
];  

Aqui eu quero comparar o VALUE que está presente no primeiro array(columnNames)e KEYS que está presente no segundo array. Se for igual, quero enviar os dados correspondentes do segundo array(rowData)para a nova matriz.

E eu quero o meu resultado final assim:

public rowData: any =[
  {Name : "Praveen",Address : "aiff",Age : "12"},
  {Name : "Akashay",Address : "xvn",Age : "15"},
  {Name : "Bala",Address : "hjk",Age : "16"}, 
  {Name : "Charu",Address : "sss",Age : "17"},
];
Praveen Sivanadiyar
fonte
Você tentou fazer isso sozinho?
TylerH 30/01

Respostas:

10

Pegue os campos de cada objeto em sua columnNamesmatriz usando .map(). Em seguida, mapeie cada objeto rowDatapara um novo objeto criado usando .reduce(), que inclui apenas as chaves da sua fieldsmatriz:

const columnNames = [
  {field : "Name"},
  {field : "Address"},
  {field : "Age"}
];

const rowData = [
  {Name : "Praveen",Address : "aiff",Age : "12",w :  "1",e :  "8"},
  {Name : "Akashay",Address : "xvn",Age : "15",w :  "2",e :  "7"},
  {Name : "Bala",Address : "hjk",Age : "16",w :  "3",e :  "6"}, 
  {Name : "Charu",Address : "sss",Age : "17",w :  "4",e :  "5"},
];  

const fields = columnNames.map(({field}) => field); // get array ["Name", "Address", "Age"]
const result = rowData.map( // map each object in rowData to a new object
  o => fields.reduce((obj, k) => ({...obj, [k]: o[k]}), {})
  //    ^^ construct the new object, using reduce, spread syntax and computed property names
);

console.log(result);
.as-console-wrapper { max-height: 100% !important;} /* ignore */

Se você puder oferecer suporte Object.fromEntries()(que [key, value]utiliza uma matriz de pares aninhados e constrói um objeto a partir deles), não há necessidade de usar .reduce():

const columnNames = [
  {field : "Name"},
  {field : "Address"},
  {field : "Age"}
];

const rowData = [
  {Name : "Praveen",Address : "aiff",Age : "12",w :  "1",e :  "8"},
  {Name : "Akashay",Address : "xvn",Age : "15",w :  "2",e :  "7"},
  {Name : "Bala",Address : "hjk",Age : "16",w :  "3",e :  "6"}, 
  {Name : "Charu",Address : "sss",Age : "17",w :  "4",e :  "5"},
];  

const fields = columnNames.map(({field}) => field);
const result = rowData.map( 
  o => Object.fromEntries(fields.map(k => [k, o[k]]))
);

console.log(result);
.as-console-wrapper { max-height: 100% !important;} /* ignore */

Nick Parsons
fonte
Oi, eu tenho um problema. Você poderia resolver o meu problema? :) Aqui está o link [ stackoverflow.com/questions/60089217/…
Sakkeer A
5

Você pode filterpropriedades do seu objeto com base na columnNamesmatriz e, em seguida, basta criar um objeto usando Object.fromEntries:

const result = rowData.map(s => Object.fromEntries(
    Object.entries(s).filter(([k, v]) => columnNames.some(cl => cl.field == k))));

Um exemplo:

let columnNames = [
  {field : "Name"},
  {field : "Address"},
  {field : "Age"}
];

let rowData = [
  {Name : "Praveen",Address : "aiff",Age : "12",w :  "1",e :  "8"},
  {Name : "Akashay",Address : "xvn",Age : "15",w :  "2",e :  "7"},
  {Name : "Bala",Address : "hjk",Age : "16",w :  "3",e :  "6"},
  {Name : "Charu",Address : "sss",Age : "17",w :  "4",e :  "5"},
];

const result = rowData.map(s => Object.fromEntries(
    Object.entries(s).filter(([k, v]) => columnNames.some(cl => cl.field == k))));
console.log(result);

Ou versão mais depurável:

const result = rowData.map(s => {
  let allProperties = Object.entries(s);
  let filteredProperties = allProperties.filter(([k, v]) => 
      columnNames.some(cl => cl.field == k));
  let result = Object.fromEntries(filteredProperties);
  return result;
})

Um exemplo:

let columnNames = [
  {field : "Name"},
  {field : "Address"},
  {field : "Age"}
];

let rowData = [
  {Name : "Praveen",Address : "aiff",Age : "12",w :  "1",e :  "8"},
  {Name : "Akashay",Address : "xvn",Age : "15",w :  "2",e :  "7"},
  {Name : "Bala",Address : "hjk",Age : "16",w :  "3",e :  "6"},
  {Name : "Charu",Address : "sss",Age : "17",w :  "4",e :  "5"},
];

const result = rowData.map(s => {
  let allProperties = Object.entries(s);
  let filteredProperties = allProperties.filter(([k, v]) => 
      columnNames.some(cl => cl.field == k));
  let result = Object.fromEntries(filteredProperties);
  return result;
})

Object.fromEntries é o método que transforma uma lista de pares de valores-chave em um objeto.

A linha a seguir significa que filtramos () o allProperies array com base no columnNamesarray.

O método some () retorna truese alguma propriedade de columnNamesexistir em allProperties:

let filteredProperties = allProperties.filter(([k, v]) => 
     columnNames.some(cl => cl.field == k)); 
Um passo adiante
fonte
Muito obrigado pela sua resposta. Eu tenho dúvida disso, eu sou um iniciante do angular 8 exatamente não sei o que é "Object.fromEntries", e também posso explicar por favor este "deixe filtradoProperties = allProperties.filter (([k, v]) => columnNames.some (cl => cl.field == k)); ". Obrigado em adavnce!
Praveen Sivanadiyar 23/01
@PraveenSivanadiyar por favor, veja a minha resposta atualizados
StepUp
@StepUp Oi, estou com um problema. Você poderia resolver o meu problema? :) Aqui está o link [ stackoverflow.com/questions/60089217/…
Sakkeer A
3

Armazene todos os nomes de campo em uma variável keysusando .map . Em seguida, percorra a matriz original e crie um objeto com as propriedades presentes emkeys

Tente assim:

let keys = this.columnNames.map(x => x.field);

this.rowData.forEach(item => {
  let obj = {}
  keys.forEach(key => {
    obj[key] = item[key]
  });
  this.result.push(obj)
});

Demonstração de trabalho

Adrita Sharma
fonte
Pode explicar o que vai acontecer aqui? keys.forEach (key => {obj [chave] = item [chave]});
Praveen Sivanadiyar 23/01
Claro, estou adicionando a descrição
Adrita Sharma 23/01
@PraveenSivanadiyar Adicionada descrição. deixe-me saber se isso foi útil
Adrita Sharma 23/01
11
objé um novo objeto vazio. obj[key] = item[key] significa que, no primeiro loop, a chave é "Nome", assim obj[key]será {Name: }e item.Nameé Praveen, portanto o resultado será {Name: "Praveen" }
Adrita Sharma
Sim, agora eu entendo e também está funcionando bem com o meu código. muito obrigada @Adrita Sharma.
Praveen Sivanadiyar 23/01