【问题标题】:Destructuring in combination with array functions [duplicate]结合数组函数进行解构[重复]
【发布时间】:2021-08-28 12:51:18
【问题描述】:

只是想知道是否可以使用数组函数(如过滤器)通过解构同时返回语句的负数和正数结果。

类似于以下内容:

let {truthys, falsys} = arr.filter(a => {
   return //magical statement that returns truthy's and falsy's?
}); 

代替:

let truthys = arr.filter(item => item.isTruthy);
let falsys = arr.filter(item => !item.isTruthy);

所以是后者的一种简写方式。 似乎在任何地方都找不到有关此的任何信息,因此可能根本不可能。 谢谢!

【问题讨论】:

  • 您可以使用.reduce() 创建一个包含两个数组的对象。
  • .filter() 返回 一个 值数组。如果您传递谓词,则对其进行解构没有多大意义。你可以做的是 group 通过谓词结果返回一个带有{ "true" : /* items that passed the predicate test */, "false": /* items that did not pass the predicate test */ }的对象,然后解构为const {true: truthys, false: falsys} = groupedValues
  • 谢谢!都会尝试一下:)
  • georg's partition implementation here 这基本上就是你所需要的。您可以将其称为parition(arr, x => !!x)(或parition(arr, Boolean),如果您愿意)。这是分区为索引为10 的数组,但如果您想分区为具有键truefalse 的对象,方法是相同的。我个人更喜欢后者,因为它更清楚result.true 是条件返回true 但最终无关紧要的所有结果。
  • const [thruthys, falsys] = partition(arr, item => item.isTruthy) 带有适当的辅助函数(参见副本)是标准方法。如果你已经有一个groupBy 助手,比如lodash 的那个,你也可以使用const {true: truthys, false: falsys} = _.groupBy(arr, item => !!item.isTruthy)

标签: javascript arrays filter destructuring shorthand


【解决方案1】:

你的想法永远不会像写的那样工作,因为来自filter 的返回必然是一个数组,而不是一个结构。如果您不介意只找到 one 值,则此变体有效:

{ a, b } = [ { a: 'yyy', b: 'yzz' }, { a: 'aww', b: 'azz' } ].find(e => e.a.startsWith('y'))

> a
'yyy'
> b
'yzz'

但仔细观察,我看到了你真正想要的,所以也许最直接的是:

const a = [ '', ' hello ', ' ', false, [], [0], [''], [' '], null, undefined, new Array(), 0, 1, -1 ]
const { truthies, falsies } = { truthies: a.filter(e => !!e), falsies: a.filter(e => !e) }
console.log(`truthies: ${JSON.stringify(truthies)}\nfalsies: ${JSON.stringify(falsies)}`)

结果:

{
  truthies: [ ' hello ', ' ', [], [ 0 ], [ '' ], [ ' ' ], [], 1, -1 ],
  falsies: [ '', false, null, undefined, 0 ]
}

编辑

灵感来自只保留一张filter 通行证,它不是很漂亮,但可以做到:

const a = [ '', ' hello ', ' ', false, [], [0], [''], [' '], null, undefined, new Array(), 0, 1, -1 ]
const false_temp = []
const { truthies, falsies } = { truthies: a.filter(e => !!e || (false_temp.push(e) && false)), falsies: false_temp }
console.log(`truthies: ${JSON.stringify(truthies)}\nfalsies: ${JSON.stringify(falsies)}`)

【讨论】:

  • 只是一些有趣的事情:0 是假的,但 new Number(0) 是真的,但 Number(0) 是假的。
【解决方案2】:

您可以使用.reduce

const getTruthysAndFalsys = (array) => {
  return array.reduce(
    ({ truthys, falsys }, item) => {
      const isTruthy = item.isTruthy

      return {
        truthys: [
          ...truthys,
          ...(isTruthy ? [item] : []),
        ],
        falsys: [
          ...falsys,
          ...(!isTruthy ? [item] : []),
        ],
      }
    },
    { truthys: [], falsys: [] }
  )
}

const array = [
  { name: 'Item 1', isTruthy: true },
  { name: 'Item 2', isTruthy: true },
  { name: 'Item 3', isTruthy: false },
  { name: 'Item 4', isTruthy: true },
  { name: 'Item 4', isTruthy: false },
]


getTruthysAndFalsys(array)
// { 
//   truthys: [ 
//     { name: 'Item 1', isTruthy: true }, 
//     { name: 'Item 2', isTruthy: true }, 
//     { name: 'Item 4', isTruthy: true }, 
//   ], 
//   falsys: [ 
//     { name: 'Item 3', isTruthy: false }, 
//     { name: 'Item 4', isTruthy: false },
//   ],
// } 

【讨论】:

    【解决方案3】:

    正如@Pointy 建议的那样,您可以通过使用Array.prototype.reduce() 将元素分成两个数组来避免两次过滤,如下所示:

    const input = [1, 0, true, false, "", "foo"];
    
    const [truthies, falsies] = input.reduce(
      ([truthies, falsies], cur) =>
        !cur ? [truthies, [...falsies, cur]] : [[...truthies, cur], falsies],
      [[], []]
    );
    
    console.log(truthies, falsies);

    【讨论】:

      猜你喜欢
      • 2019-09-25
      • 1970-01-01
      • 2021-11-24
      • 1970-01-01
      • 2017-02-02
      • 2019-05-28
      • 1970-01-01
      • 2012-10-27
      • 2020-10-01
      相关资源
      最近更新 更多