履歴ソート

ネット上に転がってなかったんで作りました。

void main() {}

/**
履歴のソートを行う。

履歴リストの中に指定データが存在すればそれを最初へ移動、
無ければリストの最初へ挿入。

Params:
	Historys = 履歴データ。

	Add = 履歴データへ追加するデータ。

Return:
	結果をT[]で返す。
	AddがHistorysの最初にあった場合Historysをそのまま返す。
	
Authors:
	sk

License:
	NYSL(http://www.kmonos.net/nysl/)

Version:
	1.01

Date:
	2009/07/07

History:
	1.01, 2009/07/07:
		Historys[$]からHistorys.lengthへ変更。
		inをやってみた。
		
	1.00, 2008/10/08:
		公開。

*/
const(T[]) HistorySort(T)(in T[] Historys, T Add) {
	foreach(i, Value; Historys) {
		if(Add == Value) {
			if(!i) {
				return Historys;
			}
			
			return [Add] ~ Historys[0..i] ~ Historys[i+1..Historys.length];
		}
	}
	return [Add] ~ Historys;
}

unittest {
	string[] list = ["a", "b", "c", "d"];
	
	assert(HistorySort(list, "a") == ["a", "b", "c", "d"]);
	assert(HistorySort(list, "b") == ["b", "a", "c", "d"]);
	assert(HistorySort(list, "c") == ["c", "a", "b", "d"]);
	assert(HistorySort(list, "d") == ["d", "a", "b", "c"]);
	
	assert(HistorySort(list, "e") == ["e", "a", "b", "c", "d"]);
	
	assert(HistorySort(list, "a") is list);

	struct TEST {
		int i;
		string s;

		static TEST opCall(int i, string s) {
			TEST test;
			
			test.i = i;
			test.s = s;

			return test;
		}
	}
	auto structs = [
		TEST(0, "a"),
		TEST(1, "b"),
		TEST(2, "c"),
		TEST(3, "d")
	];
	
	assert(HistorySort(structs, TEST(-1, "Z")) == TEST(-1, "Z") ~ structs);
	assert(HistorySort(structs, TEST(-2, "a")) == TEST(-2, "a") ~ structs);

	assert(HistorySort(structs, TEST(3, "d")) == [TEST(3, "d"), TEST(0, "a"), TEST(1, "b"), TEST(2, "c")]);
	assert(HistorySort(structs, TEST(4, "e")) == [TEST(4, "e"), TEST(0, "a"), TEST(1, "b"), TEST(2, "c"), TEST(3, "d")]);
	assert(HistorySort(structs, TEST(0, "a")) is structs);

}