匹配有序数组

时间:2012-07-25 09:40:43

标签: javascript arrays node.js

我正在尝试创建一个Javascript卡片游戏,但我需要匹配列表中的4个后续数字。但我总是创建一些疯狂的分层循环,如:

cards = [{card:'h7'},{card:'c8'},{card:'h9'},{card:'st'}]
var sorted = ['7','8','9','t','j','q','k','a']      

var found4 = false
for(var i =0;i < 5;i++){
    var found = 0;        
    for(var j = 0;j < 4;j++){             
        for(var c in cards){
            if(cards[c].card.charAt(1) == sorted[i+j]){
                found++
            }
        }
    }
    if(found == 4){
        found4 = true
    }
}

是否有更好的方法来匹配数组?

一些输入示例:

'7','8','9','t'  => true
'j','q','k','a'  => true
'7','8','k','a'  => false
'j','k','7','a'  => false

(输入未排序)

4 个答案:

答案 0 :(得分:1)

您可以为Array编写原型方法(您可以参考以下post

Array.prototype.contains = function(obj) {
    var i = this.length;
    while (i--) {
        if (this[i] == obj) {
            return i;
        }
    }
    return false;
}

var sorted = ['7', '8', '9', 't', 'j', 'q', 'k', 'a']

function check(arr) {
    index = sorted.contains(arr[0])
    if (index === false) {
        return false;
    }
    count = 1
    for (var i = 1; i < 4; i++) {
            sortedIndex = index + i > sorted.length ? index + i - sorted.length : index + i
        if (sorted[sortedIndex] == arr[i]) count++;
        }
        if (count == 4) {
            return true;
        }
        return false;
    }

console.log(check(['j','q','k','a']))​

你可以看到它有效here

答案 1 :(得分:0)

我会有适合和价值的单独字段。这样就可以更容易地测试值是否有序。请注意,下面的代码不包括范围检查或其他验证,但我假设已经处理了。

// Suit is [c]lubs, [d]iamonds, [h]earts, or [s]pades
// Value is from Ace (1) to King (13). Jack is 11, and Queen is 12. 
cards = [
    {suit:'h', value: 7 } // 7 of hearts
    {suit:'c', value: 8 } // 8 of clubs
    {suit:'h', value: 9 } // 9 of hearts
    {suit:'s', value: 10 } // Ten of spades
    {suit:'s', value: 11 } // Jack of spades
]

if (cards.length <= 1) 
{
    // Having 0 or 1 cards means they are, by definition, in order.
    return true;
}

// Test each card (starting with the second) to ensure that it is 
// 1 greater than it's predecessor.
var previousValue = cards[0].value;
for(var i = 1; i < cards.length; i++){
    if (previousValue + 1 != cards[i].value)
    {
         // This card is not the next card in sequence, so 
         // the hand is not in order.
         return false;
    }
}

return true;

答案 2 :(得分:0)

首先,你的算法应该适用于所有数组(没有固定的长度等),所以让chars找到:

var tofind = cards.map(function(c){return c.card.charAt(1);});

当你的所有作品都有一个长度时,有一个非常简单的功能可以帮助你:

return sorted.join("").indexOf(tofind.join(""))!=-1;

但是,我完全不了解你的做法。这个循环:

for (var c in cards)
    if (cards[c].card.charAt(1) == sorted[i+j])
        found++

对我来说似乎很奇怪。首先,cards是一个数组,所以不要使用for-in-loop。但是,如果您搜索所有要匹配的当前信件的卡片,这与订单有什么关系?

答案 3 :(得分:0)

使用Underscore并保留数据结构的可能解决方案

function test(seq,expected) {
    var res=isSequence(seq);
    if (res===expected)
        console.log( seq.join(',')+" : success");
    else
        console.log( seq.join(',')+" : fail");
}

function isSequence(seq) {
    var sorted = ['7','8','9','t','j','q','k','a'], l=seq.length, i, ix;
    if (l===0) return true;

    ix=_.indexOf(sorted, seq[0]);
    if (ix===-1) return false;
    if (ix>sorted.length-l) return false;

    for (i=1;i<l;i++) {
        if ( sorted[ix+i]!==seq[i] )
            return false;
    }

    return true;
}

var cards = [{card:'h7'},{card:'c8'},{card:'h9'},{card:'st'}]

test( _.map(cards, function(obj) {
    return obj.card.charAt(1);
}), true );

test(['7','8','9','t'] , true);
test(['j','q','k','a'] , true);
test(['7','8','k','a'] , false);
test(['j','k','7','a'] , false);

小提琴http://jsfiddle.net/KDrDy/2/