3

私の脳には数学ニューロンがないので、私はこれを回避する方法を見つけるのに少し苦労しています。

3つのパラメーターを受け取る単純なjavascript関数を作成する必要があります。

  • X要素(値は一意のID)を持つ1次元の通常のインデックス付き配列
  • 選択するターゲットID
  • 返す要素の量

3番目のパラメーターは、要素のセットを返すように関数に要求します。ターゲットIDを持つ要素は、結果の中央または隣にあります。

関数の結果も配列になるはずです。

より視覚的な説明にするためのいくつかの例:

function([100,120,140,160,180,200], 120, 3)
// should return [100,120,140]

function([100,120,140,160,180,200], 160, 4)
// should return [140,160,180,200]

function([100,120,140,160,180,200], 180, 5)
// should return [140,160,180,200,100]

最後の例で取り上げたケースは、私が現在試みているコードを書いているときに私を混乱させるものですが、奇妙な条件、多数のifステートメント、および一般的に回避策のように見えるコードを書いていることに気付きます。また、パラメーター3がパラメーター1の要素の量よりも大きい場合は、私にとっては少し頭がおかしいです。

このコードはバグがあり、単に適切ではないと感じているため、このコードを続行するのは危険だと感じています。確かに、適切な数学のスキルを持っている人は、私がこれをよりエレガントな方法で達成する方法を理解するために必要な理論を私に提供することができます。

理論や擬似コードで十分ですが、誰かがこのようなものを手元に用意している場合は、遠慮なく共有してください。

ありがとう!

(これが私がこれまでに書いたものです-プロトタイプJSクラスの実装に基づいています)

var CBasicMatrix=Class.create({

    initialize: function(elementList){
        this.elementList=elementList;
    },

    select: function(id, amount){
        if(amount>this.elementList.length) 
            amount=this.elementList.length;
        if(!this.elementList.length) return false;
        var elementIndex=this.elementList.indexOf(id);
        if(elementIndex==-1) return false;
        var isRound=amount%2==0;
        var amountHalf=isRound ? (amount/2) : (Math.ceil(amount/2)-1);
        // [464,460,462,461,463]
        var result=[];
        if(elementIndex-amountHalf >= 0) {
            var startIndex=(elementIndex-amountHalf);
            for(i=startIndex;i<=startIndex+amount;i++){
                result.push(this.elementList[i];
            }
        } else {
            // more seemingly stupid iterative code coming here 
        }

    }

});

編集:これをより理解しやすくするために、私は目的を述べます。このコードは、複数の要素(パラメーター3)が同時に表示される一種のスライドショーに使用されることになっています。パラメータ1は、HTML宣言に表示される正しい順序での合計要素(のID)のリストです。パラメータ2は現在選択されている要素であるため、中央に表示されます。

4

3 に答える 3

2

これが私の解決策です:

function method(arr, value, n) {
    var result = [],
        len = arr.length,
        index = arr.indexOf(value);

    for (var i = 0; index > -1 && i < n ; i++) {
        result.push(arr[(len + index - ~~(n / 2) + (n % 2 ^ 1) + i) % len]);
    }

    return result;
}

テスト:

var arr = [100, 120, 140, 160, 180, 200];

method(arr, 120, 3);  // [100, 120, 140]
method(arr, 160, 4);  // [140, 160, 180, 200]
method(arr, 180, 5);  // [140, 160, 180, 200, 100]
method(arr, 100, 3);  // [200, 100, 120]
于 2013-01-28T21:22:08.200 に答える
0

疑似コードを提供することでお手伝いします:

1. 一致するものがない場合は、空の配列を返す必要があります。

2. 一致する場合は、3 番目のパラメーターを 2 で除算するだけで結果を取得し、見つかった要素のインデックスから前の結果を引いて 3 番目のパラメーターの値までループし、要素を新しい配列に格納します。

3. 新しい配列を返します。

更新: あなたのコードを見ましたが、問題はありません。

于 2013-01-28T20:39:43.923 に答える
0

慎重にデバッグし、私のアプローチを考え直した後、適切で安全と思われる解決策を見つけることができました。これはさらに最適化できると確信しています。誰か提案があれば、遠慮なく共有してください。

var CBasicMatrix=Class.create({

    initialize: function(elementList){
        this.elementList=elementList;
    },

    select: function(id, amount){
        if(amount>this.elementList.length) 
            amount=this.elementList.length;
        if(!this.elementList.length) return false;
        var elementIndex=this.elementList.indexOf(id);
        if(elementIndex==-1) return false;
        var isRound=amount%2==0;
        var amountHalf=isRound ? (amount/2) : (Math.floor(amount/2));
        var result=[];
        var startIndex=(elementIndex-amountHalf);
        var endIndex=(startIndex+amount-1);
        var targetIndex=0;
        for(i=startIndex;i<=endIndex;i++){
            targetIndex=i;
            if(i>this.elementList.length-1) targetIndex=i-this.elementList.length;
            if(i<0) targetIndex=i+this.elementList.length;
            result.push(this.elementList[targetIndex]);
        }
        return result;
    }

});
于 2013-01-28T21:15:16.573 に答える