3

由于我的大脑中缺乏数学神经元,我很难找到解决这个问题的方法。

我需要创建一个简单的 javascript 函数,它将接收三个参数:

  • 具有 X 元素的一维正常索引数组(值是唯一 ID)
  • 要选择的目标 ID
  • 要返回的元素数量

第三个参数将要求函数返回一组元素,具有目标 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 是所有元素(的 ID)的列表,它们按照它们出现在 HTML 声明中的正确顺序排列。参数 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. 如果匹配,则只需将第三个参数除以 2,然后获取结果,然后从找到的元素的索引减去前一个结果循环,直到第三个参数的值,然后将元素存储在一个新数组中。

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 回答