卦#
[1]:
#r "nuget:YiJingFramework.PrimitiveTypes"
using YiJingFramework.PrimitiveTypes;
- YiJingFramework.PrimitiveTypes, 4.0.1
卦是由若干具有阴阳属性的爻组成的。通常来说,常用的卦一般只具有三根爻(八卦)或六根爻(六十四卦),但是这里的 Gua 支持任意的爻数。
YiJingFramework.PrimitiveTypes.GuaWithFixedCount 提供了只支持固定爻数的卦,从而能够及时在编译期发现错误。
创建#
Gua 其实就是一个不可变的、有序的爻的集合,可以通过以下方式来创建它:
[2]:
var dui = new Gua(Yinyang.Yang, Yinyang.Yang, Yinyang.Yin);
Console.WriteLine(dui);
var qian = new Gua(Enumerable.Repeat(Yinyang.Yang, 6));
Console.WriteLine(qian);
110
111111
虽然其顺序本身是可以颠倒的,但是我们约定取易气上行、先来居下、由下至上之意,即序号小的在下、序号大的在上(所谓上下即常用的卦画的上下),如上例“阳阳阴”表示兑卦而非巽卦。包括 YiJingFramework.EntityRelations 和 YiJingFramework.Annotating.Zhouyi 在内的各种包,都是按照由下至上的理解方式来提供功能的。
Gua 实现了 IReadOnlyList ,因此可以当作列表使用。无论是通过索引器访问,还是通过 foreach 遍历,都是由下至上的顺序:
[3]:
var dui = new Gua(Yinyang.Yang, Yinyang.Yang, Yinyang.Yin);
Console.WriteLine(dui);
Console.WriteLine($"{dui[0]:C}{dui[1]:C}{dui[2]:C}");
Console.WriteLine($"{string.Join(',', dui)}");
110
阳阳阴
Yang,Yang,Yin
Gua 和 string 的相互转换#
先前的示例已经显示了 Gua.ToString 的效果。这里考虑到 Gua 支持任意的爻数,让它返回 "乾" 、 "兑" 、 "离" 、 "震" 等结果并不合适。因此不同于五行、干支、阴阳等类型,它返回的是一组数字,其中 0 表示阴爻、 1 表示阳爻。如果需要得到卦名,可以尝试使用 YiJingFramework.Annotating.Zhouyi 。
如果仅仅只是为了得到卦名, YiJingFramework.Annotating.Zhouyi 可能有些笨重了,或许自己实现一个转换还是比较方便的。
同样的,Gua 也提供了 Parse 和 TryParse 方法,支持从字符串转换到 Gua 。
Gua 和 byte[] 的相互转换#
除 string 外, Gua 和 byte[] 之间也可以相互转换:
[4]:
static IEnumerable<Yinyang> GetRandomLines()
{
Random random = new Random(0);
for (; ; )
yield return (Yinyang)random.Next(0, 2);
}
var gua = new Gua(GetRandomLines().Take(30));
Console.WriteLine(gua);
var byteArray = gua.ToBytes();
Console.WriteLine(Convert.ToHexString(byteArray));
var gua2 = Gua.FromBytes(byteArray);
Console.WriteLine(gua == gua2);
111101101000101011101110111110
6F51775F
True
这种转换一般只会在非常特殊的场合下使用。而且即使需要使用,一般也不需要关注得到的 byte[] 具体是什么值,只需要知道它可以正确还原就足够了。
在转换时,会使用 1 表示阳、 0 表示阴,越低位所表示的爻也越靠下。由于爻的个数是不确定的,在最高位会额外写一个 1 以表示解析的起点(也可以叫终点)。举例而言,兑卦“阳阳阴”,转为数字得 [1, 1, 0](左侧是低位,右侧是高位);然后最高位添一,得 [1, 1, 0, 1] ;填充为八的整数倍,得 [1, 1, 0, 1, 0, 0, 0, 0] ,这就是最后的结果了。但常规的数字写法是左高右低的,即得到的是 [0b0000_1011] 。又如“阳阳阳阴阳阳阳阳阳”:
阳阳阳阴 阳阳阳阳 阳
-> 1,1,1,0, 1,1,1,1, 1
-> 1,1,1,0, 1,1,1,1, 1,1
-> (1110 1111) (1100 0000)
-> 0b0000_0011 at bytes[1]
0b1111_0111 at bytes[0]
-> [0b1111_0111, 0b0000_0011]
8765 4321 |9
其中特别要注意的是,最高位的 1 表示结束,而不是一根爻,因此比如在取错卦时,不能把它一同取反。因此,这样的转换其实并没有太大的作用,只有非常特殊的情况下可能用到。