【问题标题】:Destructuring an array of objects with es6使用 es6 解构对象数组
【发布时间】:2017-11-08 19:10:59
【问题描述】:

例如,我正在尝试将具有三个属性的对象数组解构为三个单独的数组

可能是这样的

const {wlAddresses,wlTokens,wlTickets} = Object.map()

const [wlAddresses,wlTokens,wlTickets] = Object.map()

Object.map() 返回类似这样的东西的地方

[{ wlAddresses: '23',
    wlTokens: 1,
    wlTickets: 3 },
  { wlAddresses: '24',
    wlTokens: 1,
    wlTickets: 2 },
  { wlAddresses: '25',
    wlTokens: 1,
    wlTickets: 3 }]

我尝试使用该方法,它只返回第一个对象,而不是后面的对象。我知道我可以通过映射对象并将所有内容作为单独的数组返回来解决这个问题,但也许我可以使用解构来做到这一点。

注意:这只是一个能不能做的问题,我不是强求答案

【问题讨论】:

  • 您将创建一个不能被覆盖的 const 变量。
  • 您是说您希望 wlAddresses 成为 ['23', '24', '25] 并对其他人类似吗?
  • 是的,无需为每个属性单独映射@loganfsmyth
  • 您能否在问题中明确指出要求仅使用解构赋值而不使用循环?见stackoverflow.com/help/how-to-ask。您尝试过哪些代码仅使用解构来填充同一分配的 N 个数组?
  • @guest271314 - 您的回答几乎不合格。您只是一遍又一遍地重复代码,而不是循环。这不是任何人都在这里寻找的。​​span>

标签: javascript ecmascript-6 destructuring


【解决方案1】:

当您有一个对象或数组并且需要提取特定项目时,解构非常有用,但这里不是这种情况。您的数据不是一个简单的对象或数组——它是一个对象数组。您将无法通过简单的分配来做到这一点。您需要将数据转换为您想要的格式。例如这样的:

let arr = [{
    wlAddresses: '23',
    wlTokens: 1,
    wlTickets: 3
  },
  {
    wlAddresses: '24',
    wlTokens: 1,
    wlTickets: 2
  },
  {
    wlAddresses: '25',
    wlTokens: 1,
    wlTickets: 3
  }
]

let r = arr.reduce((acc, curr) => {
    for ([key, value] of Object.entries(curr)) {
        if (! acc[key]) acc[key] = []
        acc[key].push( curr[key])
    }
    return acc
}, {})


const {wlAddresses,wlTokens,wlTickets} = r

console.log(wlAddresses,wlTokens,wlTickets)

【讨论】:

  • 支持一种合理的编码方式。试图只通过解构来做到这一点只会导致一团糟。这些是清晰、清晰、简洁、易于理解的代码。
【解决方案2】:

假设您的数组中的每个对象都将具有完全相同的相同的键,您可以只映射它。

const data = [{wlAddresses:'23',wlTokens:1,wlTickets:3},{wlAddresses:'24',wlTokens:1,wlTickets:2},{wlAddresses:'25',wlTokens:1,wlTickets:3}];
    
const r = Object.keys(data[0]).map((v) => ({ [v]: data.map((c) => c[v]) }));

console.log(JSON.stringify(r));

【讨论】:

  • 这不是我正在寻找的解决方案我知道它可以通过映射来完成
  • @MoeElsharif 您的实际问题并未明确要求不使用循环来达到预期结果。
  • @guest271314 我非常怀疑它是否可以在没有循环的情况下实现。
  • @Kinduser 是的,无需使用循环即可实现要求。
  • @guest271314 那你为什么要发布一个有两个循环的解决方案?
【解决方案3】:

您可以使用嵌套循环和Object.entries()

let o = [{"wlAddresses":"23","wlTokens":1,"wlTickets":3},{"wlAddresses":"24","wlTokens":1,"wlTickets":2},{"wlAddresses":"25","wlTokens":1,"wlTickets":3}];

let entries = Object.entries(o);
    let res = Array.from({length:entries.length}).fill([]);
    for (let [, {wlAddresses,wlTokens,wlTickets}] of entries) {   
      Object.entries({wlAddresses,wlTokens,wlTickets})
      .forEach(([, prop], index) => {
        res[index] = [...res[index], prop]
      })
    }
    
let [wlAddresses,wlTokens,wlTickets] = res;

console.log(wlAddresses,wlTokens,wlTickets);

单独使用解构赋值

let o = [{"wlAddresses":"23","wlTokens":1,"wlTickets":3},{"wlAddresses":"24","wlTokens":1,"wlTickets":2},{"wlAddresses":"25","wlTokens":1,"wlTickets":3}];

let len = o.length;

let [wlAddresses,wlTokens,wlTickets] = Array.from({length:len}, () => []);

let i = 0;

if (i < len) {
  ({wlAddresses:wlAddresses[wlAddresses.length]
  , wlTokens:wlTokens[wlTokens.length]
  , wlTickets:wlTickets[wlTickets.length]} = o[i]);
  console.log(wlAddresses,wlTokens,wlTickets);
  ++i;
} else {
  console.log("done");
  console.log(wlAddresses,wlTokens,wlTickets);
}

if (i < len) {
  ({wlAddresses:wlAddresses[wlAddresses.length]
  , wlTokens:wlTokens[wlTokens.length]
  , wlTickets:wlTickets[wlTickets.length]} = o[i]);
  console.log(wlAddresses,wlTokens,wlTickets);
  ++i;
} else {
  console.log("done");
  console.log(wlAddresses,wlTokens,wlTickets);
}

if (i < len) {
  ({wlAddresses:wlAddresses[wlAddresses.length]
  , wlTokens:wlTokens[wlTokens.length]
  , wlTickets:wlTickets[wlTickets.length]} = o[i]);
  console.log(wlAddresses,wlTokens,wlTickets);
  ++i;
} else {
  console.log("done");
  console.log(wlAddresses,wlTokens,wlTickets);
}

if (i < len) {
  ({wlAddresses:wlAddresses[wlAddresses.length]
  , wlTokens:wlTokens[wlTokens.length]
  , wlTickets:wlTickets[wlTickets.length]} = o[i]);
  console.log(wlAddresses,wlTokens,wlTickets);
  ++i;
} else {
  console.log("done");
  console.log(wlAddresses,wlTokens,wlTickets);
}

在第二个硬编码的 sn-p 处使用带有代码的循环

let o = [{"wlAddresses":"23","wlTokens":1,"wlTickets":3},{"wlAddresses":"24","wlTokens":1,"wlTickets":2},{"wlAddresses":"25","wlTokens":1,"wlTickets":3}];

let len = o.length;

let [wlAddresses,wlTokens,wlTickets] = [[], [], []];

let i = 0;

while (i < len) {
  ({wlAddresses:wlAddresses[wlAddresses.length]
  , wlTokens:wlTokens[wlTokens.length]
  , wlTickets:wlTickets[wlTickets.length]} = o[i]);
  ++i;
}
  
console.log("done");
console.log(wlAddresses,wlTokens,wlTickets);

【讨论】:

  • 看起来有点复杂。你测试了吗?
  • 嵌套循环的整个想法是我一开始并不想要的东西
  • @MoeElsharif 是的,该要求仅使用破坏性赋值是可能的,但可能需要相同数量或更多的代码才能到达目标的赋值源。 “优雅”是什么意思?
  • @Kinduser 是的,在发布之前测试过代码。在更新的答案中查看 stacksn-ps
  • @guest271314 现在不是硬编码解决方案吗?
猜你喜欢
  • 2020-02-18
  • 2017-07-24
  • 2018-08-30
  • 2020-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-23
相关资源
最近更新 更多