alim1990
alim1990

Reputation: 4972

How can we transform a nested array inside an object into one concatenated string value separated by commas?

I have the following sample array:

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

I need to transform it into something like:

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

In this case, I added all nested arrays inside a an element of the mainArray into one single string value.

What I've done so far is, I extracted the key names of the mainArray:

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

And made a loop to check the type of each element inside of the mainArray, and if it's an object I will concat the values of the nested array into one single string:

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)

This line console.log(elem[idx][key]) is always returning the following:

{address1: "Lebanon"}

{address2: "USA"}

{address1: "UK"}

{address2: "France"}

Take note that here address1 and address2 are simple examples, as my real data contain multiple nested arrays, and each one have different new key names.

I tried to do the following:

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

But it returned [Object, Object].

So how can I transform a nested array into single concatenated string value?

Here is a stackblitz.

Upvotes: 1

Views: 55

Answers (3)

Denis Pavlov
Denis Pavlov

Reputation: 27

    {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]}
      }, {}
    )
  }
)```

Upvotes: 0

StepUp
StepUp

Reputation: 38094

Just use map and use Object.values to get values from object:

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

An example:

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);

If you don't know whether the key is array, then you can try to use reduce method:

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);

An example:

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);

Upvotes: 2

Nenad Vracar
Nenad Vracar

Reputation: 122037

You could use recursive function to get addresses that will work on any nested structure and get the value if the key starts with address and value is not an object.

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)

Upvotes: 1

Related Questions