Javascript 中的循环排名实施
Circular Ranking implementation in Javascript
在 javascript 中是否有建立非线性排名层次结构的方法,例如 a>b>c>a?
其中类似:
> a>b
true
> b>c
true
> c>a
true
能一直保持一致吗?
您可以创建在转换时改变自身的对象:
let x = { valueOf: () => this.v = ~this.v };
console.log(x < x);
let a = b = c = x;
console.log(a < b && b < c && c < a);
对于不变的对象是不可能的,因为带有比较运算符的 Number 是可传递的。
注意:valueOf 用于 <
到 Number 的隐式转换。 ~this.v
只是在这种情况下缩短初始化的一个技巧,~undefined === -1
。之后 this.v
在 -1
和 0
之间交替。
这有一个问题,当 valueOf
只被调用一次时它会反转。另一种方法是使用不断增加的计数器。我认为无法检测到 valueOf
调用是否来自比较。
let counter = 0;
let x = { valueOf: () => counter++ };
console.log(x < x);
let a = b = c = x;
console.log(a < b && b < c && c < a);
console.log(x.valueOf());
console.log(a < b && b < c && c < a);
你指的是cyclic order。例如,考虑一年中的几个月:
+----> March -----+
| |
| v
+----> February April -----+
| |
| v
+----> January May -----+
| |
| v
December June
^ |
| |
+----- November July <----+
^ |
| |
+----- October August <----+
^ |
| |
+--- September <--+
在循环顺序中,说“一月在三月之前”这样的话是没有意义的,因为它并不总是在三月之前。不过,“八月过后,一月在三月前”,“二月后,三月在一月前”之类的话,倒是说得通。
用编程术语来说:
after(August, January, March); // true
after(February, March, January); // true
还有一些技巧可以让您编写如下代码:
after(August), January < March; // true
after(February), January > March; // true
以下是让它发挥作用的方法:
const [ March
, April
, May
, June
, July
, August
, September
, October
, November
, December
, January
, February ] = cycle();
console.log((after(August), January < March)); // true
console.log((after(February), January > March)); // true
function* cycle(n = 1, j = 0) {
for (let i = 0; true; i++, n++) {
yield {
valueOf: () => (i + j) % n,
get after() { j = n - i; }
};
}
}
function after(x) {
return x.after;
}
有趣的是,您知道三月是罗马历的第一个月吗?想想看:
- 三月标志着 Spring 的开始,新生活的季节。因此,一年的开始恰逢新生命的开始。
- 如果三月是第一个月,那么九月、十月、十一月和十二月分别是七月、八月、九月和十月。因此,它们被称为九月(七分之一)、十月(八分之一)、十一月(九分之一)和十二月(十分之一)。
无论如何,希望对您有所帮助。
在 javascript 中是否有建立非线性排名层次结构的方法,例如 a>b>c>a?
其中类似:
> a>b
true
> b>c
true
> c>a
true
能一直保持一致吗?
您可以创建在转换时改变自身的对象:
let x = { valueOf: () => this.v = ~this.v };
console.log(x < x);
let a = b = c = x;
console.log(a < b && b < c && c < a);
对于不变的对象是不可能的,因为带有比较运算符的 Number 是可传递的。
注意:valueOf 用于 <
到 Number 的隐式转换。 ~this.v
只是在这种情况下缩短初始化的一个技巧,~undefined === -1
。之后 this.v
在 -1
和 0
之间交替。
这有一个问题,当 valueOf
只被调用一次时它会反转。另一种方法是使用不断增加的计数器。我认为无法检测到 valueOf
调用是否来自比较。
let counter = 0;
let x = { valueOf: () => counter++ };
console.log(x < x);
let a = b = c = x;
console.log(a < b && b < c && c < a);
console.log(x.valueOf());
console.log(a < b && b < c && c < a);
你指的是cyclic order。例如,考虑一年中的几个月:
+----> March -----+
| |
| v
+----> February April -----+
| |
| v
+----> January May -----+
| |
| v
December June
^ |
| |
+----- November July <----+
^ |
| |
+----- October August <----+
^ |
| |
+--- September <--+
在循环顺序中,说“一月在三月之前”这样的话是没有意义的,因为它并不总是在三月之前。不过,“八月过后,一月在三月前”,“二月后,三月在一月前”之类的话,倒是说得通。
用编程术语来说:
after(August, January, March); // true
after(February, March, January); // true
还有一些技巧可以让您编写如下代码:
after(August), January < March; // true
after(February), January > March; // true
以下是让它发挥作用的方法:
const [ March
, April
, May
, June
, July
, August
, September
, October
, November
, December
, January
, February ] = cycle();
console.log((after(August), January < March)); // true
console.log((after(February), January > March)); // true
function* cycle(n = 1, j = 0) {
for (let i = 0; true; i++, n++) {
yield {
valueOf: () => (i + j) % n,
get after() { j = n - i; }
};
}
}
function after(x) {
return x.after;
}
有趣的是,您知道三月是罗马历的第一个月吗?想想看:
- 三月标志着 Spring 的开始,新生活的季节。因此,一年的开始恰逢新生命的开始。
- 如果三月是第一个月,那么九月、十月、十一月和十二月分别是七月、八月、九月和十月。因此,它们被称为九月(七分之一)、十月(八分之一)、十一月(九分之一)和十二月(十分之一)。
无论如何,希望对您有所帮助。