帮助在包含模运算符的if语句中查找模式

时间:2018-10-09 01:34:35

标签: javascript function modulus

我在一个个人项目中工作,发现自己在重复很多代码:

// this code is in a function with params k & dir

// where i equals a number from 0-2 inclusive
// j = (i + 1) % 2
// k = (j + 1) % 2
// The objective is to change a.x, a.y, b.x, & b.y



1.  if(k === 0 && dir === -1) { a.x = dir *  array[k].x; a.y = dir * array[k].y; b.x = dir * -array[i].x; b.y = dir * -array[i].y; }
2.  if(k === 0 && dir ===  1) { a.x = dir *  array[i].x; a.y = dir * array[i].y; b.x = dir * -array[k].x; b.y = dir * -array[k].y; }
3.
4.  if(k === 1 && dir === -1) { a.x = dir * -array[i].x; a.y = dir * array[i].y; b.x = dir * -array[i].x; b.y = dir * -array[i].y; }
5.  if(k === 1 && dir ===  1) { a.x = dir * -array[i].x; a.y = dir * array[i].y; b.x = dir * -array[i].x; b.y = dir * -array[i].y; }
6.  
7.  if(k === 2 && dir === -1) { a.x = dir * -array[j].x; a.y = dir * array[j].y; b.x = dir *  array[i].x; b.y = dir * -array[i].y; }
8.  if(k === 2 && dir ===  1) { a.x = dir * -array[i].x; a.y = dir * array[i].y; b.x = dir *  array[j].x; b.y = dir * -array[j].y; }

我一直在尝试减少代码两天而没有任何运气,并且我坦率地认为,必须有一种方法可以不使用所有这些if语句。

我只是想朝着正确的方向前进,尽管非常欢迎一个完整的解决方案。

到目前为止,我尝试再次使用模运算符,但是问题出在诸如行78之类的部分,因为数组索引根据对象是否为{ {1}}或a。因此,我相信至少必须有两个if语句,但是我只是迷路了。

再一次,这比什么都成为难题更重要,所以我希望至少对您编码专家来说很有趣:)

编辑

代码已经可以使用,只需重复一下,我希望找到一个更简洁的解决方案。所有值都是数字,ba都是包含b的对象。

为清楚起见,分为两个对象:

{ x: undefined, y: undefined }

每行末尾的注释显示输入=>输出,其中 // for a if(k === 0 && dir === -1) { a.x = dir * array[k].x; a.y = dir * array[k].y; } // (0, -1) => (0) if(k === 0 && dir === 1) { a.x = dir * array[i].x; a.y = dir * array[i].y; } // (0, 1) => (1) if(k === 1 && dir === -1) { a.x = dir * -array[i].x; a.y = dir * array[i].y; } // (1, -1) => (2) if(k === 1 && dir === 1) { a.x = dir * -array[i].x; a.y = dir * array[i].y; } // (1, 1) => (2) if(k === 2 && dir === -1) { a.x = dir * -array[j].x; a.y = dir * array[j].y; } // (2, -1) => (1) if(k === 2 && dir === 1) { a.x = dir * -array[i].x; a.y = dir * array[i].y; } // (2, 1) => (0) // for b if(k === 0 && dir === -1) { b.x = dir * -array[i].x; b.y = dir * -array[i].y; } // (0, -1) => (1) if(k === 0 && dir === 1) { b.x = dir * -array[k].x; b.y = dir * -array[k].y; } // (0, 1) => (0) if(k === 1 && dir === -1) { b.x = dir * -array[i].x; b.y = dir * -array[i].y; } // (1, -1) => (2) if(k === 1 && dir === 1) { b.x = dir * -array[i].x; b.y = dir * -array[i].y; } // (1, 1) => (2) if(k === 2 && dir === -1) { b.x = dir * array[i].x; b.y = dir * -array[i].y; } // (2, -1) => (0) if(k === 2 && dir === 1) { b.x = dir * array[j].x; b.y = dir * -array[j].y; } // (2, 1) => (1) ,输出值是给(k, dir) => output的索引。

array是函数范围之外的数组。

Edit2

array

1 个答案:

答案 0 :(得分:2)

此代码可能存在问题。自从我开始编写该问题以来,这个问题已经改变,而且我可能没有跟上。但是我认为这至少可以显示一种避免重复的技术:

const rules = [[0, -1, 'k', 'k', 'i', 'i'], [0, 1, 'i', 'i', 'k', 'k'], /* ... */]

const foo = (i, j, k, dir, array) => {
    const idxs = {i, j, k}
    const a = {}, b = {}
    const [,, ax, ay, bx, by] = rules.find(([rk, rd, ..._]) => rk === k && rd === dir)
    a.x = dir *  array[idxs[ax]].x
    a.y = dir *  array[idxs[ay]].y
    b.x = dir * -array[idxs[bx]].x 
    b.y = dir * -array[idxs[by]].y
    return {a, b}
}

console.log(foo(0, 1, 0, -1, [{x: 1, y: 2}]))

重要的部分是规则列表,它实际上捕获了您的逻辑,而idxs对象则允许将这些规则转换为实际值。可能有一种进一步的方法,对a,b,x和y进行类似的处理。但是我认为这达到了可读性的平衡。