Mam następującą przykładową tablicę:

mainArray = [
    {id: 15475, name: 'Ali', gender: 'Male', addresses: [
      {address1: 'Lebanon'}, 
      {address2: 'USA'}]
    },
    {id: 15475, name: 'Emily', gender: 'Female', addresses: [
      {address1: 'UK'}, 
      {address2: 'France'}]
    },
];

Muszę to przekształcić w coś takiego:

mainArray = [
    {id: 15475, name: 'Ali', gender: 'Male', addresses: 'Lebanon, USA'},
    {id: 15475, name: 'Emily', gender: 'Female', addresses: 'UK, France }
];

W tym przypadku dodałem wszystkie zagnieżdżone tablice wewnątrz elementu mainArray do jednej wartości ciągu.

Do tej pory wyodrębniłem nazwy kluczy z mainArray:

extractedIndexes = ['id', 'name', 'gender', 'addresses'];

Zrobiłem pętlę, aby sprawdzić typ każdego elementu wewnątrz mainArray, a jeśli jest to obiekt, połączę wartości zagnieżdżonej tablicy w jeden ciąg:

for (const idx of this.extractedIndexes) {
  console.log(idx)
  this.mainArray.forEach((elem) => {
    let newItem = '';
    if (typeof (elem[idx]) == 'object') {
      elem[idx] = Object.keys(elem[idx]).forEach((key) => {
        console.log(elem[idx][key])
        // Add it to the field
      })
      console.log(elem[idx])
    }
  })
}
console.log(this.mainArray)

Ta linia console.log(elem[idx][key]) zawsze zwraca:

{address1: "Lebanon"}

{address2: "USA"}

{address1: "UK"}

{address2: "France"}

Zwróć uwagę, że tutaj address1 i address2 to proste przykłady, ponieważ moje prawdziwe dane zawierają wiele zagnieżdżonych tablic, a każda z nich ma inne nowe nazwy kluczy.

Próbowałem wykonać następujące czynności:

if (typeof (elem[idx]) == 'object') {
  elem[idx] = elem[idx].toString().split(',')
  // Add it to the field
  console.log(elem[idx])
}

Ale zwróciło [Object, Object].

Jak więc mogę przekształcić zagnieżdżoną tablicę w pojedynczą połączoną wartość ciągu?

Oto stackblitz.

1
alim1990 3 kwiecień 2020, 13:12

3 odpowiedzi

Najlepsza odpowiedź

Po prostu użyj map i użyj Object.values, aby pobrać wartości z obiektu:

mainArray.map(({addresses, ...rest}) => ({...rest, addresses: 
    addresses.map(s => Object.values(s)).join(', ')}) );

Przykład:

let mainArray = [
    {id: 15475, name: 'Ali', gender: 'Male', addresses: [
      {address1: 'Lebanon'},
      {address2: 'USA'}]
    },
    {id: 15475, name: 'Emily', gender: 'Female', addresses: [
      {address1: 'UK'},
      {address2: 'France'}]
    },
];

const result = mainArray.map(({addresses, ...rest}) => ({...rest, addresses: addresses.map(s => Object.values(s)).join(', ')}) );
console.log(result);

Jeśli nie wiesz, czy klucz jest tablicą, możesz spróbować użyć metody reduce:

const result = mainArray.reduce((a, c)=> {
  for (const key in c) {
      if (Array.isArray(c[key]))
        c[key] = c[key].map(s => Object.values(s)).join(', ');
  }
  a.push(c);
  return a;
},[])
console.log(result);

Przykład:

let mainArray = [
    {id: 15475, name: 'Ali', gender: 'Male', addresses: [
      {address1: 'Lebanon'},
      {address2: 'USA'}]
    },
    {id: 15475, name: 'Emily', gender: 'Female', addresses: [
      {address1: 'UK'},
      {address2: 'France'}]
    },
];

const result = mainArray.reduce((a, c)=> {
  for (const key in c) {
      if (Array.isArray(c[key]))
        c[key] = c[key].map(s => Object.values(s)).join(', ');
  }
  a.push(c);
  return a;
},[])
console.log(result);
2
StepUp 3 kwiecień 2020, 12:31

Możesz użyć funkcji rekurencyjnej, aby uzyskać adresy, które będą działać na dowolnej zagnieżdżonej strukturze i uzyskać wartość, jeśli klucz zaczyna się od address, a wartość nie jest obiektem.

const data =[{"id":15475,"name":"Ali","gender":"Male","addresses":[{"address1":"Lebanon"},{"address2":"USA"}]},{"id":15475,"name":"Emily","gender":"Female","addresses":[{"address1":"UK"},{"address2":"France"}]}]

const flat = (data, prev = '') => {
  let sep = prev ? ', ' : ''
  let result = '';

  for (let i in data) {
    if (typeof data[i] == 'object') {
      result += flat(data[i], prev + result)
    } else if (i.startsWith('address')) {
      result += sep + data[i]
    }
  }

  return result
}

const result = data.map(({
    addresses,
    ...rest
  }) =>
  ({ ...rest,
    addresses: flat(addresses)
  }))


console.log(result)
1
Nenad Vracar 3 kwiecień 2020, 10:44
    {id: 15475, name: 'Ali', gender: 'Male', addresses: [
      {address1: 'Lebanon'}, 
      {address2: 'USA'}]
    },
    {id: 15475, name: 'Emily', gender: 'Female', addresses: [
      {address1: 'UK'}, 
      {address2: 'France'}]
    },
];<br>

function toString(arro) {
  return arro.reduce(
    (acc, rec) => {
      return [...acc, Object.values(rec)]
    }, []
  ).join(',')
}

const res = mainArray.map(
  it => {
    return Object.keys(it).reduce(
      (acc, item) => {
        if (typeof it[item] === 'object') {
          return {...acc, [item]: toString(it[item])}
        }
        return {...acc, [item]: it[item]}
      }, {}
    )
  }
)```
0
Denis Pavlov 3 kwiecień 2020, 13:28