Interactive Extensions(Ix)

本文的主题为对 Ix 库,对 LINQ 的扩展。

Buffer

Ix.NET Buffer

Ix.NET BufferTest

Buffer 方法将源序列按照起始位置和元素个数分成若干组,形成序列的序列。

var rng = Enumerable.Range(0, 10);
var res = rng.Buffer(3).ToList();
// res.Count == 4
// res[0] == { 0, 1, 2 }
// res[1] == { 3, 4, 5 }
// res[2] == { 6, 7, 8 }
// res[3] == { 9 }
var rng = Enumerable.Range(0, 10);
var res = rng.Buffer(5).ToList();
// res.Count == 2
// res[0] == { 0, 1, 2, 3, 4 }
// res[1] == { 5, 6, 7, 8, 9 }
var rng = Enumerable.Empty<int>();
var res = rng.Buffer(5).ToList();
// res.Count == 0
var rng = Enumerable.Range(0, 10);
var res = rng.Buffer(3, 2).ToList();
// res.Count == 5
// res[0] == { 0, 1, 2 }
// res[1] == { 2, 3, 4 }
// res[2] == { 4, 5, 6 }
// res[3] == { 6, 7, 8 }
// res[4] == { 8, 9 }
var rng = Enumerable.Range(0, 10);
var res = rng.Buffer(3, 4).ToList();
// res.Count == 3
// res[0] == { 0, 1, 2 }
// res[1] == { 4, 5, 6 }
// res[2] == { 8, 9 }

Case

Ix.NET Case

Ix.NET CaseTest

Case 方法根据回调函数的结果选择并返回 Dictionary 参数中的序列。

var x = 1;
var d = 'd';
var res = EnumerableEx.Case<int, char>(() => x, new Dictionary<int, IEnumerable<char>>
{
{ 0, new[] { 'a' } },
{ 1, new[] { 'b' } },
{ 2, new[] { 'c' } },
{ 3, EnumerableEx.Defer(() => new[] { d }) },
});
// res.Single() == 'b'
// res.Single() == 'b'
x = 0;
// res.Single() == 'a'
x = 2;
// res.Single() == 'c'
x = 3;
// res.Single() == 'd'
d = 'e';
// res.Single() == 'e'
x = 4;
Assert.True(res.IsEmpty());
var x = 1;
var d = 'd';
var res = EnumerableEx.Case<int, char>(() => x, new Dictionary<int, IEnumerable<char>>
{
{ 0, new[] { 'a' } },
{ 1, new[] { 'b' } },
{ 2, new[] { 'c' } },
{ 3, EnumerableEx.Defer(() => new[] { d }) },
}, new[] { 'z' });
// res.Single() == 'b'
// res.Single() == 'b'
x = 0;
// res.Single() == 'a'
x = 2;
// res.Single() == 'c'
x = 3;
// res.Single() == 'd'
d = 'e';
// res.Single() == 'e'
x = 4;
// res.Single() == 'z'

Catch

Ix.NET Catch

Ix.NET CatchTest

var ex = new MyException();
var res = EnumerableEx.Throw<int>(ex).Catch<int, MyException>(e => { Assert.Same(ex, e); return new[] { 42 }; }).Single();
// res == 42
var ex = new MyException();
var res = EnumerableEx.Throw<int>(ex).Catch<int, Exception>(e => { Assert.Same(ex, e); return new[] { 42 }; }).Single();
// res == 42
var ex = new MyException();
AssertThrows<MyException>(() =>
{
EnumerableEx.Throw<int>(ex).Catch<int, InvalidOperationException>(e => { Assert.True(false); return new[] { 42 }; }).Single();
});
var xs = Enumerable.Range(0, 10);
var res = xs.Catch<int, MyException>(e => { Assert.True(false); return new[] { 42 }; });
// res == xs
var xss = new[] { Enumerable.Range(0, 5), Enumerable.Range(5, 5) };
var res = EnumerableEx.Catch(xss);
// res == Enumerable.Range(0, 5)
var xss = new[] { Enumerable.Range(0, 5), Enumerable.Range(5, 5) };
var res = xss.Catch();
// res == Enumerable.Range(0, 5)
var xss = new[] { Enumerable.Range(0, 5), Enumerable.Range(5, 5) };
var res = xss[0].Catch(xss[1]);
// res == Enumerable.Range(0, 5)
var xss = new[] { Enumerable.Range(0, 5).Concat(EnumerableEx.Throw<int>(new MyException())), Enumerable.Range(5, 5) };
var res = EnumerableEx.Catch(xss);
// res == Enumerable.Range(0, 10)
var xss = new[] { Enumerable.Range(0, 5).Concat(EnumerableEx.Throw<int>(new MyException())), Enumerable.Range(5, 5) };
var res = xss.Catch();
// res == Enumerable.Range(0, 10)
var xss = new[] { Enumerable.Range(0, 5).Concat(EnumerableEx.Throw<int>(new MyException())), Enumerable.Range(5, 5) };
var res = xss[0].Catch(xss[1]);
// res == Enumerable.Range(0, 10)
var e1 = new MyException();
var ex1 = EnumerableEx.Throw<int>(e1);
var e2 = new MyException();
var ex2 = EnumerableEx.Throw<int>(e2);
var e3 = new MyException();
var ex3 = EnumerableEx.Throw<int>(e3);
var xss = new[] { Enumerable.Range(0, 2).Concat(ex1), Enumerable.Range(2, 2).Concat(ex2), ex3 };
var res = xss.Catch();
var e = res.GetEnumerator();
HasNext(e, 0);
HasNext(e, 1);
HasNext(e, 2);
HasNext(e, 3);
AssertThrows<MyException>(() => e.MoveNext(), ex => ex == e3);
var xs = new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var res = xs.Catch<int, MyException>(e => { Assert.False(true); return new[] { 42 }; });
// res == xs
var xss = new[] { new[] { 0, 1, 2, 3, 4 }, new[] { 5, 6, 7, 8, 9 } };
var res = EnumerableEx.Catch(xss);
// res == Enumerable.Range(0, 5)));
var xss = new[] { new[] { 0, 1, 2, 3, 4 }, new[] { 5, 6, 7, 8, 9 } };
var res = xss.Catch();
// res == Enumerable.Range(0, 5)));
var xss = new[] { new[] { 0, 1, 2, 3, 4 }, new[] { 5, 6, 7, 8, 9 } };
var res = xss[0].Catch(xss[1]);
// res == Enumerable.Range(0, 5)));
var xss = new[] { new[] { 0, 1, 2, 3, 4 }.Concat(EnumerableEx.Throw<int>(new MyException())), new[] { 5, 6, 7, 8, 9 } };
var res = EnumerableEx.Catch(xss);
// res == Enumerable.Range(0, 10)));
var xss = new[] { new[] { 0, 1, 2, 3, 4 }.Concat(EnumerableEx.Throw<int>(new MyException())), new[] { 5, 6, 7, 8, 9 } };
var res = xss.Catch();
// res == Enumerable.Range(0, 10)));
var xss = new[] { new[] { 0, 1, 2, 3, 4 }.Concat(EnumerableEx.Throw<int>(new MyException())), new[] { 5, 6, 7, 8, 9 } };
var res = xss[0].Catch(xss[1]);
// res == Enumerable.Range(0, 10)));
var e1 = new MyException();
var ex1 = EnumerableEx.Throw<int>(e1);
var e2 = new MyException();
var ex2 = EnumerableEx.Throw<int>(e2);
var e3 = new MyException();
var ex3 = EnumerableEx.Throw<int>(e3);
var xss = new[] { new[] { 0, 1 }.Concat(ex1), new[] { 2, 3 }.Concat(ex2), ex3 };
var res = xss.Catch();
var e = res.GetEnumerator();
HasNext(e, 0);
HasNext(e, 1);
HasNext(e, 2);
HasNext(e, 3);
AssertThrows<MyException>(() => e.MoveNext(), ex => ex == e3);

Concat

Ix.NET Concat

Ix.NET ConcatTest

Concat 方法将若干序列连接起来。

var res = new[]
{
new[] { 1, 2, 3 },
new[] { 4, 5 }
}.Concat();
// res == { 1, 2, 3, 4, 5 }
var i = 0;
var xss = Enumerable.Range(0, 3).Select(x => Enumerable.Range(0, x + 1)).Do(_ => ++i);
var res = xss.Concat().Select(x => i + " - " + x).ToList();
/*
res == {
"1 - 0",
"2 - 0",
"2 - 1",
"3 - 0",
"3 - 1",
"3 - 2",
}
*/
var res = EnumerableEx.Concat(
new[] { 1, 2, 3 },
new[] { 4, 5 }
);
// res == { 1, 2, 3, 4, 5 }

Create

Ix.NET Create

Ix.NET CreateTest

Create 方法使用协程创建序列。

private static IEnumerator<int> MyEnumerator()
{
yield return 1;
yield return 2;
}
var hot = false;
var res = EnumerableEx.Create<int>(() =>
{
hot = true;
return MyEnumerator();
});
// hot == false
var e = res.GetEnumerator();
// hot == true
HasNext(e, 1);
HasNext(e, 2);
NoNext(e);
hot = false;
var f = ((IEnumerable)res).GetEnumerator();
// hot == true
var xs = EnumerableEx.Create<int>(async yield =>
{
var i = 0;
while (i < 10)
{
await yield.Return(i++);
}
});
var j = 0;
foreach (var elem in xs)
{
// elem == j
j++;
}
// j == 10
var xs = EnumerableEx.Create<int>(async yield =>
{
var i = 0;
while (true)
{
if (i == 10)
{
await yield.Break();
return;
} await yield.Return(i++);
}
});
var j = 0;
foreach (var elem in xs)
{
// elem == j
j++;
}
// j == 10

Defer

Ix.NET Defer

Ix.NET DeferTest

Defer 方法使用返回序列的回调函数创建序列。

var i = 0;
var n = 5;
var xs = EnumerableEx.Defer(() =>
{
i++;
return Enumerable.Range(0, n);
});
// i == 0
// xs.ToList() == Enumerable.Range(0, n)
// i == 1
n = 3;
// xs.ToList() == Enumerable.Range(0, n)
// i == 2

Distinct / DistinctUntilChanged

Ix.NET Distinct / DistinctUntilChanged

Ix.NET DistinctTest

Ix.NET DistinctUntilChangedTest

Distinct 方法去除序列中的重复元素。

DistinctUntilChanged 方法去除序列中邻近的重复元素。

var res = Enumerable.Range(0, 10).Distinct(x => x % 5).ToList();
// res == Enumerable.Range(0, 5)
}
private class MyEqualityComparer : IEqualityComparer<int>
{
public bool Equals(int x, int y)
{
return x % 2 == y % 2;
} public int GetHashCode(int obj)
{
return EqualityComparer<int>.Default.GetHashCode(obj % 2);
}
}
var res = Enumerable.Range(0, 10).Distinct(x => x % 5, new MyEqualityComparer()).ToList();
// res =={ 0, 1 }
var res = new[] { 1, 2, 2, 3, 3, 3, 2, 2, 1 }.DistinctUntilChanged().ToList();
// res == { 1, 2, 3, 2, 1 }
var res = new[] { 1, 1, 2, 3, 4, 5, 5, 6, 7 }.DistinctUntilChanged(x => x / 2).ToList();
// res == { 1, 2, 4, 6 }

Do / DoWhile

Ix.NET Do / DoWhile

Ix.NET DoTest

Ix.NET DoWhileTest

Do 方法让序列在枚举元素时执行指定的函数。

DoWhile 方法通过模拟 do ... while 语句生成新的序列:无限次重复源序列中的所有元素直到指定条件不再满足为止。

var n = 0;
Enumerable.Range(0, 10).Do(x => n += x).ForEach(_ => { });
// n == 45
var n = 0;
Enumerable.Range(0, 10).Do(x => n += x, () => n *= 2).ForEach(_ => { });
// n == 90
var ex = new MyException();
var ok = false;
AssertThrows<MyException>(() =>
EnumerableEx.Throw<int>(ex).Do(x => { Assert.True(false); }, e => { Assert.Equal(ex, e); ok = true; }).ForEach(_ => { })
);
// ok == true
var obs = new MyObserver();
Enumerable.Range(0, 10).Do(obs).ForEach(_ => { });
// obs.Done == true
// obs.Sum == 45
private class MyObserver : IObserver<int>
{
public int Sum;
public bool Done; public void OnCompleted()
{
Done = true;
} public void OnError(Exception error)
{
throw new NotImplementedException();
} public void OnNext(int value)
{
Sum += value;
}
}
var sum = 0;
var done = false;
Enumerable.Range(0, 10).Do(x => sum += x, ex => { throw ex; }, () => done = true).ForEach(_ => { });
// done == true
// sum == 45
var x = 5;
var res = EnumerableEx.DoWhile(EnumerableEx.Defer(() => new[] { x }).Do(_ => x--), () => x > 0).ToList();
// res == { 5, 4, 3, 2, 1 }
var x = 0;
var res = EnumerableEx.DoWhile(EnumerableEx.Defer(() => new[] { x }).Do(_ => x--), () => x > 0).ToList();
// res == { 0 }

Expand

Ix.NET Expand

Ix.NET ExpandTest

var res = new[] { 0 }.Expand(x => new[] { x + 1 }).Take(10).ToList();
// res == Enumerable.Range(0, 10)
var res = new[] { 3 }.Expand(x => Enumerable.Range(0, x)).ToList();
var exp = new[] {
3,
0, 1, 2,
0,
0, 1,
0
};
// res == exp

Finally

Ix.NET Finally

Ix.NET FinallyTest

var done = false;
var xs = Enumerable.Range(0, 2).Finally(() => done = true);
// done == false
var e = xs.GetEnumerator();
// done == false
HasNext(e, 0);
// done == false
HasNext(e, 1);
// done == false
NoNext(e);
// done == true
var done = false;
var xs = Enumerable.Range(0, 2).Finally(() => done = true);
// done == false
var e = xs.GetEnumerator();
// done == false
HasNext(e, 0);
// done == false
e.Dispose();
// done == true
var done = false;
var ex = new MyException();
var xs = EnumerableEx.Throw<int>(ex).Finally(() => done = true);
// done == false
var e = xs.GetEnumerator();
// done == false
try
{
HasNext(e, 0);
Assert.True(false);
}
catch (MyException ex_)
{
Assert.Same(ex, ex_);
}
// done == true

ForEach

Ix.NET ForEach

Ix.NET ForEachTest

ForEach 方法枚举序列,为每一个元素调用指定函数,有不带下标和带下标两个版本。

var n = 0;
Enumerable.Range(5, 3).ForEach(x => n += x);
// n == 5 + 6 + 7
var n = 0;
Enumerable.Range(5, 3).ForEach((x, i) => n += x * i);
// n == 5 * 0 + 6 * 1 + 7 * 2

For

Ix.NET For

Ix.NET ForTest

For 方法枚举源序列,将每一个元素都映射为一个序列,然后连接这些序列。

var res = EnumerableEx.For(new[] { 1, 2, 3 }, x => Enumerable.Range(0, x)).ToList();
// res == { 0, 0, 1, 0, 1, 2 }

Generate

Ix.NET Generate

Ix.NET GenerateTest

Generate 方法通过模拟 for 循环来生成序列。

var res = EnumerableEx.Generate(0, x => x < 5, x => x + 1, x => x * x).ToList();
// res == { 0, 1, 4, 9, 16 }

Hide

Ix.NET Hide

Ix.NET HideTest

Hide 方法隐藏序列的真实类型。

var xs = new List<int> { 1, 2, 3 };
var ys = xs.Hide();
// ys is not List<int>
// xs == ys

If

Ix.NET If

Ix.NET IfTest

If 方法根据给定条件(谓词函数)的结果

  1. 在两个给定序列中选择其中之一。
  2. 在给定序列和空序列中选择其中之一。
var x = 5;
var res = EnumerableEx.If(() => x > 0, new[] { +1 }, new[] { -1 });
// res.Single() == +1
x = -x;
// res.Single() == -1
var x = 5;
var res = EnumerableEx.If(() => x > 0, new[] { +1 });
// res.Single() == +1
x = -x;
// res.IsEmpty() == true

IgnoreElements

Ix.NET IgnoreElements

Ix.NET IgnoreElementsTest

IgnoreElements 方法将源序列转换为空序列。

var n = 0;
Enumerable.Range(0, 10).Do(_ => n++).IgnoreElements().Take(5).ForEach(_ => { });
// n == 10

IsEmpty

Ix.NET IsEmpty

Ix.NET IsEmptyTest

IsEmpty 方法判断序列是否为空。

// Enumerable.Empty<int>().IsEmpty() == true
// new[] { 1 }.IsEmpty() == false

Max / MaxBy

Ix.NET Max / MaxBy

Ix.NET MaxTest

Ix.NET MaxByTest

Max / MaxBy 方法返回序列中的最大值。

Max 带有一个用于比较序列中元素的 comparer 参数(IComparer 接口的实例)。

MaxBy 带有一个用于转换序列中元素的 keySelector 参数(回调函数)。

private class Mod7Comparer : IComparer<int>
{
public int Compare(int x, int y)
{
return Comparer<int>.Default.Compare(x % 7, y % 7);
}
}
// new[] { 2, 5, 3, 7 }.Max(new Mod7Comparer()) == 5
var res = new[] { 2, 5, 0, 7, 4, 3, 6, 2, 1 }.MaxBy(x => x % 3);
// res == { 2, 5, 2 }

Memoize

Ix.NET Memoize

Ix.NET MemoizeTest

Min / MinBy

Ix.NET Min / MinBy

Ix.NET MinTest

Ix.NET MinByTest

Min / MinBy 方法返回序列中的最小值。

Min 带有一个用于比较序列中元素的 comparer 参数(IComparer 接口的实例)。

MinBy 带有一个用于转换序列中元素的 keySelector 参数(回调函数)。

private class Mod3Comparer : IComparer<int>
{
public int Compare(int x, int y)
{
return Comparer<int>.Default.Compare(x % 3, y % 3);
}
}
// new[] { 5, 3, 7 }.Min(new Mod3Comparer()) == 3
var res = new[] { 2, 5, 0, 7, 4, 3, 6, 2, 1 }.MinBy(x => x % 3);
// res == { 0, 3, 6 }

OnErrorResumeNext

Ix.NET OnErrorResumeNext

Ix.NET OnErrorResumeNextTest

OnErrorResumeNext 方法将若干序列连接起来,忽略序列中抛出的异常。

var xs = new[] { 1, 2 };
var ys = new[] { 3, 4 };
var res = xs.OnErrorResumeNext(ys);
// res == { 1, 2, 3, 4 }
var xs = new[] { 1, 2 }.Concat(EnumerableEx.Throw<int>(new MyException()));
var ys = new[] { 3, 4 };
var res = xs.OnErrorResumeNext(ys);
// res == { 1, 2, 3, 4 }
var xs = new[] { 1, 2 };
var ys = new[] { 3, 4 };
var zs = new[] { 5, 6 };
var res = EnumerableEx.OnErrorResumeNext(xs, ys, zs);
// res == { 1, 2, 3, 4, 5, 6 }
var xs = new[] { 1, 2 }.Concat(EnumerableEx.Throw<int>(new MyException()));
var ys = new[] { 3, 4 };
var zs = new[] { 5, 6 };
var res = EnumerableEx.OnErrorResumeNext(xs, ys, zs);
// res == { 1, 2, 3, 4, 5, 6 }
var xs = new[] { 1, 2 };
var ys = new[] { 3, 4 };
var res = new[] { xs, ys }.OnErrorResumeNext();
// res == { 1, 2, 3, 4 }
var xs = new[] { 1, 2 }.Concat(EnumerableEx.Throw<int>(new MyException()));
var ys = new[] { 3, 4 };
var res = new[] { xs, ys }.OnErrorResumeNext();
// res == { 1, 2, 3, 4 }

Publish

Ix.NET Publish

Ix.NET PublishTest

Repeat

Ix.NET Repeat

Ix.NET RepeatTest

EnumerableEx.Repeat(n) 返回由元素 n 组成的无限序列。

x.Repeat() 返回由序列 x 中的所有元素无限次重复而生成的序列。

x.Repeat(n) 返回由序列 x 中的所有元素经过 n 次重复生成的序列。

var xs = EnumerableEx.Repeat(42).Take(1000);
// xs.All(x => x == 42) == true
// xs.Count() == 1000
var i = 0;
var xs = new[] { 1, 2 }.Do(_ => i++).Repeat();
var res = xs.Take(10).ToList();
// res.Count == 10
// res.Buffer(2).Select(b => b.Sum()).All(x => x == 3) == true
// i == 10
var i = 0;
var xs = new[] { 1, 2 }.Do(_ => i++).Repeat(5);
var res = xs.ToList();
// res.Count == 10
// res.Buffer(2).Select(b => b.Sum()).All(x => x == 3) == true
// i == 10

Retry

Ix.NET Retry

Ix.NET RetryTest

var xs = Enumerable.Range(0, 10);
var res = xs.Retry();
// res == xs
var xs = Enumerable.Range(0, 10);
var res = xs.Retry(2);
// res == xs
var ex = new MyException();
var xs = Enumerable.Range(0, 2).Concat(EnumerableEx.Throw<int>(ex));
var res = xs.Retry(2);
var e = res.GetEnumerator();
HasNext(e, 0);
HasNext(e, 1);
HasNext(e, 0);
HasNext(e, 1);
AssertThrows<MyException>(() => e.MoveNext(), ex_ => ex == ex_);

Return

Ix.NET Return

Ix.NET ReturnTest

Return 方法返回由一个元素组成的序列。

// EnumerableEx.Return(42).Single() == 42

Scan

Ix.NET Scan

Ix.NET ScanTest

Scan 方法转换序列:

  • Scan 带有一个有返回值的二元函数和一个可选的初值。
  • 结果序列的第 1 项没有初值时等于源序列的第 1 项,有初值时等于将二元函数应用到初值和源序列的第 1 项后所得到的结果。
  • 结果序列的第 n + 1 项等于将二元函数应用到结果序列的第 n 项和源序列的第 n + 1 项后所得到的结果。
var res = Enumerable.Range(0, 5).Scan((n, x) => n + x).ToList();
// res == { 1, 3, 6, 10 }
var res = Enumerable.Range(0, 5).Scan(10, (n, x) => n - x).ToList();
// res == { 10, 9, 7, 4, 0 }

SelectMany

Ix.NET SelectMany

Ix.NET SelectManyTest

SelectMany 方法将源序列中的所有元素都映射成指定序列,然后连接这些序列。

var res = new[] { 1, 2 }.SelectMany(new[] { 'a', 'b', 'c' }).ToList();
// res == { 'a', 'b', 'c', 'a', 'b', 'c' }

Share

Ix.NET Share

Ix.NET ShareTest

SkipLast

Ix.NET SkipLast

Ix.NET SkipLastTest

SkipLast 方法略过序列尾部的 n 个元素,返回其余元素组成的序列。

var e = Enumerable.Range(0, 5);
var r = e.SkipLast(3).ToList();
// r == e.Take(2)

StartWith

Ix.NET StartWith

Ix.NET StartWithTest

StartWith 方法在序列之前插入指定的(1 个或多个)元素。

var e = Enumerable.Range(1, 5);
var r = e.StartWith(0).ToList();
// r == Enumerable.Range(0, 6)

TakeLast

Ix.NET TakeLast

Ix.NET TakeLastTest

TakeLast 方法返回由序列尾部的 n 个元素组成的序列。

var e = Enumerable.Range(0, 5);
var r = e.TakeLast(3).ToList();
// r == e.Skip(2)

Throw

Ix.NET Throw

Ix.NET ThrowTest

Using

Ix.NET Using

Ix.NET UsingTest

While

Ix.NET While

Ix.NET WhileTest

While 方法通过模拟 while 语句生成新的序列:只要指定条件满足就无限次重复源序列中的所有元素。

var x = 5;
var res = EnumerableEx.While(() => x > 0, EnumerableEx.Defer(() => new[] { x }).Do(_ => x--)).ToList();
// res == { 5, 4, 3, 2, 1 }
var x = 0;
var res = EnumerableEx.While(() => x > 0, EnumerableEx.Defer(() => new[] { x }).Do(_ => x--)).ToList();
// res == { }

ReactiveX 学习笔记(11)对 LINQ 的扩展的更多相关文章

  1. ReactiveX 学习笔记(0)学习资源

    ReactiveX 学习笔记 ReactiveX 学习笔记(1) ReactiveX 学习笔记(2)创建数据流 ReactiveX 学习笔记(3)转换数据流 ReactiveX 学习笔记(4)过滤数据 ...

  2. python3.4学习笔记(三) idle 清屏扩展插件

    python3.4学习笔记(三) idle 清屏扩展插件python idle 清屏问题的解决,使用python idle都会遇到一个常见而又懊恼的问题——要怎么清屏?在stackoverflow看到 ...

  3. Spring 源码学习笔记11——Spring事务

    Spring 源码学习笔记11--Spring事务 Spring事务是基于Spring Aop的扩展 AOP的知识参见<Spring 源码学习笔记10--Spring AOP> 图片参考了 ...

  4. Ext.Net学习笔记11:Ext.Net GridPanel的用法

    Ext.Net学习笔记11:Ext.Net GridPanel的用法 GridPanel是用来显示数据的表格,与ASP.NET中的GridView类似. GridPanel用法 直接看代码: < ...

  5. SQL反模式学习笔记11 限定列的有效值

    目标:限定列的有效值,将一列的有效字段值约束在一个固定的集合中.类似于数据字典. 反模式:在列定义上指定可选值 1. 对某一列定义一个检查约束项,这个约束不允许往列中插入或者更新任何会导致约束失败的值 ...

  6. golang学习笔记11 golang要用jetbrain的golang这个IDE工具开发才好

    golang学习笔记11   golang要用jetbrain的golang这个IDE工具开发才好  jetbrain家的全套ide都很好用,一定要dark背景风格才装B   从File-->s ...

  7. Spring MVC 学习笔记11 —— 后端返回json格式数据

    Spring MVC 学习笔记11 -- 后端返回json格式数据 我们常常听说json数据,首先,什么是json数据,总结起来,有以下几点: 1. JSON的全称是"JavaScript ...

  8. Python3+Selenium3+webdriver学习笔记11(cookie处理)

    #!/usr/bin/env python# -*- coding:utf-8 -*-'''Selenium3+webdriver学习笔记11(cookie处理)'''from selenium im ...

  9. 并发编程学习笔记(11)----FutureTask的使用及实现

    1. Future的使用 Future模式解决的问题是.在实际的运用场景中,可能某一个任务执行起来非常耗时,如果我们线程一直等着该任务执行完成再去执行其他的代码,就会损耗很大的性能,而Future接口 ...

  10. 《C++ Primer Plus》学习笔记11

    <C++ Primer Plus>学习笔记11 第17章 输入.输出和文件 <<<<<<<<<<<<<< ...

随机推荐

  1. js对象-平铺与嵌套的互相转换

    一个json对象,包含嵌套关系,传输过来的时候是平铺的,顺序打乱,用parentCode属性来关联,如下 { "1":{ "name": "中国&qu ...

  2. 高通平台读写nv总结

    一,引言      1. 什么是NV       高通平台的NV,保存了系统运行过程中各个模块可能用到的一些参数值,它是以单个文件的形式保存在EFS中,但用户是不能随意访问的,只能通过QXDM来进行读 ...

  3. python 基本数据类型常用方法总结

    [引言] python中基本数据类型的有很多常用方法,熟悉这些方法有助于不仅提升了编码效率,而且能写出高质量代码,本文做总结 int .bit_length:返回二进制长度 str 切片索引超出不会报 ...

  4. c#语言---数据类型

    整型 值类型 名称                        CTS类型                                说明                             ...

  5. gcc 工作流程

    gcc常用参数: 1:-v/--version 2:-I :指定头文件包含路径 3:-c :将汇编文件生成一个二级制文件,得到.o文件 4:-o :指定生产的文件名 5:-g :gdb调试的时候需要加 ...

  6. ECharts动态加载堆叠柱状图的实例

    一.引入echarts.js文件(下载页:http://echarts.baidu.com/download.html) 二.HTML代码: <div style="width: 10 ...

  7. redis中key过期事件

    刚到新公司一个月左右,有个新需求,想做定时任务,比如在用户注册时间的3天后推送用户一条消息. 从刚开始脑子里面闪现的数据库轮询,立马否定掉(浪费资源),再到linux系统的定时任务,但是当用户量过大时 ...

  8. 点击DIV随机换颜色

    <!DOCTYPE html> <html>     <head>         <meta charset="UTF-8">   ...

  9. python、javascript中的不可变对象

    比如python中str是不变对象,而list是可变对象,javascript中str也是不变对象,而array是可变对象 python的例子: >>> a = 'abc' > ...

  10. update 中实现子查询

    mysql 在update中实现子查询的方式   当使用mysql条件更新时--最先让人想到的写法 UPDATE buyer SET is_seller=1 WHERE uid IN (SELECT  ...