javascript - Array.reduce 将多维数组转换为对象数组

标签 javascript arrays functional-programming poker

在我的扑克应用程序中,我有一组手牌,每手牌都是随机选择的具有值(value)和花色的卡片对象数组:

[ [ { value: 5, suit: 's' },
    { value: 4, suit: 's' },
    { value: 6, suit: 'c' },
    { value: 11, suit: 'd' },
    { value: 12, suit: 'c' } ],
  [ { value: 9, suit: 'd' },
    { value: 12, suit: 'h' },
    { value: 8, suit: 'c' },
    { value: 12, suit: 's' },
    { value: 2, suit: 's' } ],
  [ { value: 4, suit: 'h' },
    { value: 6, suit: 's' },
    { value: 10, suit: 'c' },
    { value: 3, suit: 'd' },
    { value: 7, suit: 'd' } ] ]

为了准备手进行评估,我想使用 Array.reduce 返回一组手对象。所以输出将是:
[ 
  { 
    values: [5, 4, 6, 11, 12],
    suits: ['s', 's', 'c', 'd', 'c'] 
  },      
  { 
    values: [9, 12, 8, 12, 2], 
    suits: ['d', 'h', 'c', 's', 's'] 
  },
  { 
    values: [4, 6, 10, 3, 7],
    suits: ['h', 's', 'c', 'd', 'd'] 
  } 
]

我尝试使用嵌套的 forEach 来实现它,但它失败了,我不知道为什么。我有两个console.log,其中的输出符合预期,但最终手与输入相同。
let temp = []
hands.forEach((el) => {
  temp = el
  el = {}
  el.values = []
  el.suits = []
  console.log(el) //expected output
  temp.forEach((obj) => {
    el.values.push(obj.value)
    el.suits.push(obj.suit)
    console.log(el) //expected output
  })
})
console.log(hands) //same as original

最佳答案

您必须考虑输入数据 ( DATA ) 和输出 ( DATA' ) 的形状

enter image description here

备注 1:1 HAND 之间的关系和 HAND'表示我们将使用 Array.prototype.map一次转型。另一方面,CARD有一个 号码:1 HAND' 的关系意思是我们将使用Array.prototype.reduce为了那个转变

enter image description here

所以请记住,当我们工作时,我们将做一个 map 减少

const data = 
  [ [ { value: 5, suit: 's' },
      { value: 4, suit: 's' },
      { value: 6, suit: 'c' },
      { value: 11, suit: 'd' },
      { value: 12, suit: 'c' } ],
    [ { value: 9, suit: 'd' },
      { value: 12, suit: 'h' },
      { value: 8, suit: 'c' },
      { value: 12, suit: 's' },
      { value: 2, suit: 's' } ],
    [ { value: 4, suit: 'h' },
      { value: 6, suit: 's' },
      { value: 10, suit: 'c' },
      { value: 3, suit: 'd' },
      { value: 7, suit: 'd' } ] ]

let output = 
  data.map(cards =>
    cards.reduce(({values, suits}, {value, suit}) => ({
      values: [...values, value],
      suits: [...suits, suit]
    }), {values: [], suits: []}))

console.log(output)


当然,这看起来有点密集,所以如果我们可以稍微降低复杂性就好了。通过为 map 制作一些 curry 适配器和 reduce我们可以表达一个可以很好地执行您的转换的函数

const data = 
  [ [ { value: 5, suit: 's' },
      { value: 4, suit: 's' },
      { value: 6, suit: 'c' },
      { value: 11, suit: 'd' },
      { value: 12, suit: 'c' } ],
    [ { value: 9, suit: 'd' },
      { value: 12, suit: 'h' },
      { value: 8, suit: 'c' },
      { value: 12, suit: 's' },
      { value: 2, suit: 's' } ],
    [ { value: 4, suit: 'h' },
      { value: 6, suit: 's' },
      { value: 10, suit: 'c' },
      { value: 3, suit: 'd' },
      { value: 7, suit: 'd' } ] ]


const map = f => xs => xs.map(f)

const reduce = f => y => xs => xs.reduce(f, y)

const handAppendCard = ({values, suits}, {value, suit}) => ({
  values: [...values, value],
  suits: [...suits, suit]
})

const makeHands =
  map (reduce (handAppendCard) ({values:[], suits:[]}))

let output = makeHands (data)

console.log(output)


这只是解决问题的一种方法。我希望你能从中学到一些东西^_^

关于javascript - Array.reduce 将多维数组转换为对象数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41233470/

相关文章:

arrays - 使用 update_user_meta 保存数组

scala - 类型级 Cats.Effect 与类型级 eff。哪个,为什么?

python - 如何在 Python 中的每一步都得到 "reduce"的结果?

javascript - 如何通过一个按钮切换 div

javascript - 在 Javascript 中使用 jSTL

java - 什么 Java 库可以将 PostgreSQL 数组文字映射到 Java 数组或列表?

Java:输入10个多项选择A、B、C、D并输出数字正确、错误和等级

java - java中方法的引用

javascript - 我们如何在通过 Controller 附加到 html 页面的 html 中使用 angularjs 作用域变量?

javascript - 如何使用 Javascript 中的字符串来验证两个单独的 JSON 字典中的数据?