使用array reduce来减少对象数组的两个属性

时间:2015-12-13 19:56:52

标签: javascript arrays

我想存储Card对象数组的套装和值的所有重复项和唯一值。每张卡都有:statesuit属性。数据结构如下所示:

value

我尝试使用cards = [ { suit: 'spades', value : 4 }, { suit: 'hearts', value : 4 }, { suit: 'spades', value : 11 }, { suit: 'spades', value : 12 } etc... ] 来检查和存储重复项和唯一值以及两者的适用性,但我在构建代码时遇到了问题。

规则:

  • 3种不同的西装
  • 4张牌(带递增值),同样适合

基本上......我需要检查每张卡片的价值和适合度......并计算重复数据和价值和套装的唯一性。我正在努力传递一系列对象并在其上使用reduce。

输出:类似

array.reduce

代码:

melds : { 
      values: [4, 4, 4]
      suits: [spades, hearts, diamonds]
},
runs : {
      values: [11, 12, 13],
      suits: ['spades', 'spades', 'spades']
}

编辑:

        function calculate(cards) {
            var my_array = cards.reduce(function(prev_array, curr, index, array){

                if (prev_array.duplicates.values.indexOf(curr) !== -1  || array.lastIndexOf(curr) !== index) {
                    prev_array.duplicates.values.push(curr);
                } else {
                    prev_array.uniques.values.push(curr);
                }

                if (prev_array.duplicates.suits.indexOf(curr) !== -1  || array.lastIndexOf(curr) !== index) {
                    prev_array.uniques.suits.push(curr);
                } else {
                    prev_array.duplicates.suits.push(curr); 
                }

                return prev_array;
            }, 
                {
                    duplicates : {
                        values : [],
                        suits : []
                    },
                    uniques : {
                        values : [],
                        suits : []
                    }
                }
            );

            return my_array;
        }

编辑2:

var values = [2, 3, 4, 5, 6, 6, 6];
var suits = ['spades', 'spades', 'spades', 'spades', 'diamonds', 'clubs', 'hearts'];

var test_values = potentialRunsAndMelds(values);
var test_suits = potentialRunsAndMelds(suits);

        function potentialRunsAndMelds(array) {
            var my_array = array.reduce(function(prev_array, curr, index, array){

                if (prev_array.duplicates.indexOf(curr) !== -1  || array.lastIndexOf(curr) !== index) {
                    prev_array.duplicates.push(curr);
                } else {
                    prev_array.uniques.push(curr);
                }
                return prev_array;
            }, 
                {
                    uniques : [],
                    duplicates : []
                }
            );

            return my_array;
        }

var values = [2, 3, 4, 5, 6, 6, 6];
var suits = ['spades', 'hearts', 'spades', 'spades', 'diamonds', 'clubs', 'spades'];

返回: var runs = Object.keys(groups.suits).map(function (suit) { var values = groups.suits[suit].sort(); var run = []; for (var i = 0; i < values.length; i++) { if (values[i+1] - values[i] === 1) { if (run.indexOf(values[i+1]) === -1) { run.push(values[i+1]); } if (run.indexOf(values[i]) === -1) { run.push(values[i]); } } } if (run.length >= 4) return run; });

[Array[4], undefined, undefined, undefined]Array[4]

的位置

我怎能不返回[2, 3, 4, 5]

我想我可以做:

undefined

2 个答案:

答案 0 :(得分:1)

你可能试图在一个reduce函数中做太多事情;也许尝试将其分解为步骤?无论如何,按价值和适合你的减速器组会简化事情。

var groups = cards.reduce(function (accumulator, card) {
  // Group by value.
  accumulator.values[card.value] = accumulator.values[card.value] || [];
  accumulator.values[card.value].push(card.suit);

  // Group by suit.
  accumulator.suits[card.suit] = accumulator.suits[card.suit] || [];
  accumulator.suits[card.suit].push(card.value);
  return accumulator;
}, {values: {}, suits: {}});

一旦你完成了这项工作,就会更容易找到融合和运行。

// Melds
var meldValues = Object.keys(groups.values).filter(function (value) {
    // Check for duplicates in this array, if so inclined.
    return groups.values[value].length >= 3;
});

// Runs
var runs = Object.keys(groups.suits).map(function (suit) {
    var values = groups.suits[suit].sort();
    // (1) iterate over values
    // (2) append each value to current 'run' as long as it's consecutive
    // (3) if not consecutive, start a new run. if duplicate, discard.
    // (4) return all runs with length >= 4
});

答案 1 :(得分:0)

好吧,我不赌博,也许我完全不理解你想要达到的目标,但在我看来,你忘了从cards数组获得属性值。

您正在传递curr

if (prev_array.duplicates.values.indexOf(curr) !== -1 ...

curr是卡片对象。

cards = [
{
    suit: 'spades',
    value : 4
},

您应该定位suitvalue,例如curr.suitcur.value

因为在JS中,对象无法轻易比较,所以lastIndexOf(object) === indexOf(object)在所有情况下均等。并且如果值已经存在,则需要检查uniques数组,因为您不能依赖lastIndexOf()

另外,因为对象不容易比较,所以用Object测试双重性是不好的。