Javascript уплощение массива внутри объекта - PullRequest
0 голосов
/ 07 апреля 2020

PS Я попробовал переполнение стека, уже ответил на вопросы о выравнивании вложенного массива внутри объекта, и они упоминаются в следующем вопросе.

Я все еще работаю над очисткой массива , Мне удалось заполнить пустые массивы и массивы с нулевыми значениями, используя следующее:

if (Array.isArray(elem[prop]) || typeof(elem[prop]) === 'object') {
  if (elem[prop].indexOf(null) !== -1 || elem[prop].length === 0) {
    // console.log(elem[prop], prop)
    elem[prop] = '';
  }
}

Предполагая, что у меня есть следующий массив:

array = [
  {
    id: 123,
    name: 'Peter',
    phone: '',
    addresses: 
    [
      { 
        address1: 'Manchester, UK', address2: 'London, UK' 
      }, 
      { 
        address1: 'Liverpool, UK', address2: 'NY, USA' 
      }
    ]
  },
  {
    id: 124,
    name: 'Sara',
    phone: '',
    addresses: [{ address1: 'London, UK', address2: 'Paris, FR' }]
  }
];

Мне нужно сгладить массив адресов, поэтому Конечный массив будет выглядеть так:

array = [
  {
    id: 123,
    name: 'Peter',
    phone: '',
    addresses_address1: 'Manchester, UK',
    addresses_address2: 'London, UK'
  },
  {
    id: 124,
    name: 'Sara',
    phone: '',
    addresses_address1: 'London, UK',
    addresses_address2: 'Paris, FR'
  }
];

Как вы сказали, первый вложенный массив с идентификатором пользователя = 123 добавляется как addresses_addres1 и addresses_address2, а второй вложенный массив удаляется:

{ 
  address1: 'Liverpool, UK', address2: 'NY, USA' 
}

Единственная причина, по которой я удаляю другие вложенные массивы из-за именования. В любом случае, я попробовал следующее решение из ответа Stack Overflow , используя concat.apply():

ngOnInit(){
  let props = [];
  var flattened = [];

  // Getting the properties of the array
  props = Array.from(new Set(this.array.flatMap(e => Object.keys(e), [])));
  // console.log(props)
  for (const elem of this.array){
    for (const prop of props) {
      if(Array.isArray(elem[prop])){
        flattened = [].concat.apply([],this.array);
      }
    }
  }
  console.log(flattened)
}

Но консольный массив такой же, как и исходный.

Затем я попытался использовать lodash:

// Method 2 using lodash
for (const elem of this.array) {
  for (const prop of props) {
    if (Array.isArray(elem[prop])) {
      elem[prop] = _.flatten(elem[prop])
    }
  }
}
console.log(this.array)

Но это не сработало, поскольку оно может работать только на таких массивах, как это: [[1,2, 'abc'], ['x', True, 'z'], 11].

Я пытался это сделать используя Vanilla JavaScript из этой статьи :

//Method 3: Vanilla JavaScript
console.log(this.array.flat())

Но также и безрезультатно.

Я пытался ответить из этого поста в переполнение стека при частичном выравнивании объекта:

//Method 4:
for (const elem of this.array) {
  for (const prop of props) {
    if (Array.isArray(elem[prop])) {
      const result = elem[prop].map(
      ({prop, ...rest}) => Object.assign(rest, ...Object.keys(prop).map(key => {[elem[prop]+"_"+prop] : elem[prop]})));
    }
  }
}
console.log(this.array)

И никакого результата тоже.

Вот stackblitz , описывающий проблему со всеми 4 методами.

1 Ответ

1 голос
/ 07 апреля 2020

Вы можете попробовать это:

array = [
  {
    id: 123,
    name: 'Peter',
    phone: '',
    addresses: 
    [{address1: 'Manchester, UK', address2: 'London, UK'}, { address1: 'Liverpool, UK', address2: 'NY, USA' }]
  },
  {
    id: 124,
    name: 'Sara',
    phone: '',
    addresses: [{ address1: 'London, UK', address2: 'Paris, FR' }]
  }
];

let count = [];
array.map(a => {
  a.addresses.map(b => {
    Object.keys(b).map((c, ind) => {
      count.push(1)
      a[c.slice(0, -1) + count.length] = Object.values(b)[ind]
    })
  })
  count = []
  delete a.addresses; 
})
console.log(array)
...