0

I'm making Rummy. I need to get all objects that match two object properties, card suit and card value in two sets of arrays.

Array A:

[
   {
      suit : 'spades',
      value : 13
   },
   {
      suit : 'hearts',
      value : 8
   },   
   ...
]

Array B

[
   {
      suit : 'spades',
      value : 11
   },
   {
      suit : 'hearts',
      value : 8
   },   
   ...
]

Result would be an Array:

[
   {
      suit : 'hearts',
      value : 8
   },   
]

I found this SO post on using functional programming and grouping, then using for in to check equality:

An efficient way to get the difference between two arrays of objects?

However this seems to be based on a single property.

So I tried:

var test_hand = testHand(Control_Panel.test_hand);
var bValues = {};
test_hand.forEach(function (test_card) {
    bValues[test_card.value] = test_card;
    bValues[test_card.suit] = test_card;
});
var tester = this.deck.filter(function (card) {
    return (card.value in bValues) && (card.suit in bValues);
});

But obviously this is going to return 2x as many cards.

Any thoughts?

2 Answers 2

3

Try this:

var a = [{
    suit: 'spades',
    value: 13
}, {
    suit: 'hearts',
    value: 8
}];

var b = [{
        suit: 'spades',
        value: 11
    }, {
        suit: 'hearts',
        value: 8
    },

];

var result = a.filter(function(v) {
    return b.filter(function(v2) {
        return (v.suit === v2.suit && v.value === v2.value);
    }).length > 0;
});

console.log(result);

Output:

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

1

A different approach would be to create a hash where the key is the combination of the suit and the value:

var a = [{
    suit: 'spades',
    value: 13
}, {
    suit: 'hearts',
    value: 8
}];

var b = [{
        suit: 'spades',
        value: 11
    }, {
        suit: 'hearts',
        value: 8
    }];

var hash = {};
var key = function (el) { return el.suite + '-' + el.value; };
b.forEach(function (el) { hash[key(el)] = true; });

// intersection between a and b
var intersection = a.filter(function (el) { return hash[key(el)]; });

// elements in a that are not in b -- removes all cards in a that are present in b
var aMinusB = a.filter(function (el) { return !hash[key(el)]; });

3 Comments

I mean, I need to basically splice out of A all cards that are in B. Sorry for the confusion!!
Shouldnt it be as simple as return (test_card.suit !== deck_card.suit && test_card.value !== deck_card.value);
So aMinusB returns has the cards that are in A that are not in B (A-B), the difference with this approach is in performance, with Will's approach you're basically looping all the elements in one array for each element in the other array (O(n2)) with this approach you are looping only each array once (O(n)) at the expense of some extra memory needed

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.