简体   繁体   English

Javascript object 内的展平数组

[英]Javascript flattening array inside an object

PS I tried some stack overflow already answered questions about flattening a nested array inside an object, and they are mentioned in the question below. PS 我尝试了一些堆栈溢出,已经回答了有关在 object 中展平嵌套数组的问题,下面的问题中提到了它们。

I am still working on cleaning an array.我仍在努力清理阵列。 I managed to fill empty and null-values arrays using the following:我设法使用以下方法填充空值和空值 arrays:

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] = '';
  }
}

Assuming I am having the following array:假设我有以下数组:

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' }]
  }
];

I need to flatten the address array, so the final array will look like this:我需要展平地址数组,所以最终的数组将如下所示:

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'
  }
];

As you say, the first nested array of user id = 123 is added as addresses_addres1 and addresses_address2 and the second nested array has been removed:正如您所说,用户 id = 123 的第一个嵌套数组添加为addresses_addres1addresses_address2 ,第二个嵌套数组已被删除:

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

The only reason I am removing other nested arrays because of the naming.由于命名,我删除其他嵌套 arrays 的唯一原因。 Anyway, I tried the following solution from a Stack Overflow answer using concat.apply() :无论如何,我使用concat.apply()Stack Overflow 答案中尝试了以下解决方案:

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

But the consoled array is the same as the original one.但控制台数组与原始数组相同。

I then tried to use lodash :然后我尝试使用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)

But it didn't works, as it only may work on arrays like this: [[1,2, 'abc'], ['x', True, 'z'], 11] .但它不起作用,因为它只能像这样在 arrays 上工作: [[1,2, 'abc'], ['x', True, 'z'], 11]

I tried to do it using Vanilla JavaScript from this article :我尝试使用本文中的 Vanilla JavaScript 来做到这一点:

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

But no result as well.但也没有结果。

I tried the answer from this post on stack overflow about partially flattening an object:我从这篇关于堆栈溢出的帖子中尝试了关于部分展平 object 的答案:

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

And no result as well.也没有结果。

Here is a stackblitz describing the issue with all 4 methods.这是一个堆栈闪电战,描述了所有 4 种方法的问题。

You could try this:你可以试试这个:

 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)

Very similar to the other answer, but using map() and spread syntax to copy each iterated object to avoid mutating the original array, and utilizing destructuring to remove the addresses property before applying its properties to the copied object in nested for...of of loops.与其他答案非常相似,但使用map()传播语法来复制每个迭代的 object 以避免改变原始数组,并利用解构来删除地址属性,然后再将其属性应用于嵌套的 object 嵌套for...of的循环。

 const 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' }], },]; const flat_array = array.map(({ addresses, ...contact }) => { const _contact = {...contact }; let i = 1; for (const address_obj of addresses) { for (const address of Object.values(address_obj)) { _contact[`address_${i++}`] = address; } } return _contact; }); console.log(flat_array);

Or a slightly more obscure solution calling Object.fromEntries() on the flatMap() ed addresses array and copying/merging it with the original contact with Object.assign()或者在flatMap() ed 地址数组上调用Object.fromEntries()并使用Object.assign()将其与原始联系人复制/合并的稍微模糊的解决方案

 const 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' }], },]; const flat_array = array.map(({ addresses, ...contact }) => { let i = 1; const address_object = Object.fromEntries( addresses.flatMap((o) => Object.values(o).map((v) => [`address_${i++}`, v])) ); return Object.assign({}, contact, address_object); }); console.log(flat_array);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM