【问题标题】:Combine 2 objects from 2 arrays in a loop?在一个循环中组合来自 2 个数组的 2 个对象?
【发布时间】:2025-12-30 07:55:11
【问题描述】:

我正在通过使用 javascript 组合一组花色对象和一组卡片对象来创建一副卡片(一组卡片对象)。

我正在使用 forEach 循环来循环花色,并且嵌套的是卡片的地图循环。

console.log 正在返回正确的对象以推送到新数组,但是 .push() 仅使用最后一个花色和最后一张牌附加一个组合对象。

我在哪里做错了?

我尝试了多种不同的循环和方法来追加到一个新数组,但没有运气。 Console.log() 返回正确的值,但我无法将正确的组合对象推送到新数组。

  // Deck of Cards
var suits = [
  { suit: "clubs", color: "black" },
  { suit: "spades", color: "black" },
  { suit: "hearts", color: "red" },
  { suit: "diamonds", color: "red" }
];

var family = [
  { name: "2", value: 2 },
  { name: "3", value: 3 },
  { name: "4", value: 4 },
  { name: "5", value: 5 },
  { name: "6", value: 6 },
  { name: "7", value: 7 },
  { name: "8", value: 8 },
  { name: "9", value: 9 },
  { name: "10", value: 10 },
  { name: "J", value: 10 },
  { name: "Q", value: 10 },
  { name: "K", value: 10 },
  { name: "A", value: 1 },
];

var deck = new Array();

suits.forEach(function (x) {
  var arr = family.map((y) => {
    var obj = Object.assign(x, y);
    console.log(obj);
    deck.push(obj);
    return obj;
  });
  
  console.log(arr);
});

console.log(deck);

【问题讨论】:

  • 一些注意事项:1.您不需要分配arr变量,因为它没有在任何地方使用(除了后面的console.log语句),2.您应该使用@ 987654323@ 而不是 .map 用于内部循环,因为您将所需的对象推送到 deck,3. 随着 .map 更新为 .forEach,您应该从中删除返回值
  • @stevendesu 您 100% 正确 - 我正在使用 .map 并将其分配给新阵列以进行故障排除。谢谢!

标签: javascript arrays object


【解决方案1】:

尝试Object.assign({}, x, y) 而不是Object.assign(x, y)。目前,您正在通过向其添加 y 的所有属性来操作 x 对象。

// Deck of Cards
var suits = [
    {suit: "clubs",color: "black"},
    {suit: "spades",color: "black"},
    {suit: "hearts",color: "red"},
    {suit: "diamonds",color: "red"}    
];

var family = [
    {name: "2",value: 2},
    {name: "3",value: 3},
    {name: "4",value: 4},
    {name: "5",value: 5},
    {name: "6",value: 6},
    {name: "7",value: 7},
    {name: "8",value: 8},
    {name: "9",value: 9},
    {name: "10",value: 10},
    {name: "J",value: 10},
    {name: "Q",value: 10},
    {name: "K",value: 10},
    {name: "A",value: 1},
];

var deck = new Array();

suits.forEach(function(x){

    var arr = family.map( (y) => {
        var obj = Object.assign({}, x, y); 
        deck.push(obj);
        return obj; 
    });

});

console.log(deck);

【讨论】:

  • 完美!我认为鉴于目标对象被返回,如果它是一个新的或现有的对象,它不会有什么不同。谢谢!
【解决方案2】:

Object.assign(x,y) 会将y 的值放到x 上。您想单独留下x,因此使用Object.assign({}, x,y) 将您的属性存储在一个新对象中。考虑下面的演示:

var suits = [
    {suit: "clubs",color: "black"},
    {suit: "spades",color: "black"},
    {suit: "hearts",color: "red"},
    {suit: "diamonds",color: "red"}    
];

var family = [
    {name: "2",value: 2},
    {name: "3",value: 3},
    {name: "4",value: 4},
    {name: "5",value: 5},
    {name: "6",value: 6},
    {name: "7",value: 7},
    {name: "8",value: 8},
    {name: "9",value: 9},
    {name: "10",value: 10},
    {name: "J",value: 10},
    {name: "Q",value: 10},
    {name: "K",value: 10},
    {name: "A",value: 1},
];

const tmp = suits.reduce((acc, s) => {
  return acc.concat(family.map(f => {
    return Object.assign({}, f, s);
  }));
}, []);

const pre = document.createElement("pre");
pre.innerHTML = JSON.stringify(tmp, null, 4);
document.body.appendChild(pre);

【讨论】:

  • 为什么是... 运算符? .concat() 可以接受数组参数,不需要传播
  • @stevendesu 你说得对,我认为它会将数组连接为数组而不是将其展平。
  • flatmap 和对象传播使这更容易:const deck = suits.flatMap(s => family.map(f => ({...s, ...f})))
  • @ScottSauyet 是的,但flatmap 没有任何 IE 支持。不过,这将是一个更清洁的解决方案。
  • 是的,总是有问题的孩子,那个浏览器!
【解决方案3】:

如果you can use flatmap,那么它可以变得更简单:

const suits = [{ suit: "clubs", color: "black" }, { suit: "spades", color: "black" }, { suit: "hearts", color: "red" }, { suit: "diamonds", color: "red" }]
const family = [{ name: "2", value: 2 }, { name: "3", value: 3 }, { name: "4", value: 4 }, { name: "5", value: 5 }, { name: "6", value: 6 }, { name: "7", value: 7 }, { name: "8", value: 8 }, { name: "9", value: 9 }, { name: "10", value: 10 }, { name: "J", value: 10 }, { name: "Q", value: 10 }, { name: "K", value: 10 }, { name: "A", value: 1 }]

const deck = suits.flatMap(s => family.map(f => ({...s, ...f})))

console.log(deck)

附带说明,订购花色梅花/钻石/红心/黑桃似乎有一种强烈的惯例(可能来自 Bridge)。英文很容易记住,因为它们是字母。)

【讨论】:

  • 不错的选择,也感谢您提醒订购西装!