Skip to content

Instantly share code, notes, and snippets.

@choeehb
Last active August 5, 2021 13:04
Show Gist options
  • Save choeehb/b9ce9677bff1e6c1aec466e779dc53b1 to your computer and use it in GitHub Desktop.
Save choeehb/b9ce9677bff1e6c1aec466e779dc53b1 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using Sirenix.OdinInspector;
using Sirenix.Utilities;
using UnityEngine;
namespace Common
{
public abstract class DictionaryTable<TId, TValue> where TId : IComparable
{
protected abstract TId GetId(TValue value);
private bool dirty;
private List<TValue> list = new List<TValue>();
public TValue FindById(TId id)
{
SortIfDirty();
var index = BinarySearch(id);
return list[index];
}
public IReadOnlyCollection<TValue> FindAll()
{
SortIfDirty();
return list;
}
private void SortIfDirty()
{
if (dirty)
list.Sort(CompareValue);
dirty = false;
}
private int CompareValue(TValue value1, TValue value2)
{
var id1 = GetId(value1);
var id2 = GetId(value2);
return id1.CompareTo(id2);
}
// return index
private int BinarySearch(TId id)
{
int search(int left, int right)
{
if (right < left)
return -1;
int mid = (left + right) / 2;
var target = list[mid];
var targetId = GetId(target);
var compared = id.CompareTo(targetId);
if (compared == -1)
return search(left, mid - 1);
if (compared == 1)
return search(mid + 1, right);
return mid;
}
if (list.Count == 0)
return -1;
return search(0, list.Count);
}
protected void Add(TValue value)
{
list.Add(value);
dirty = true;
}
protected void AddAll(IEnumerable<TValue> list)
{
list.ForEach(Add);
}
}
//--------------------------------------------------------
public struct MySheet
{
public int Id;
public string Value;
}
public class MyTable : DictionaryTable<int, MySheet>
{
protected override int GetId(MySheet value) => value.Id;
public MyTable()
{
Add(new MySheet { Id = 4, Value = "4" });
Add(new MySheet { Id = 1, Value = "1" });
Add(new MySheet { Id = 5, Value = "5" });
Add(new MySheet { Id = 3, Value = "3" });
Add(new MySheet { Id = 2, Value = "2" });
}
}
public class TestTest
{
[TestCase(1, "1")]
[TestCase(2, "2")]
[TestCase(3, "3")]
[TestCase(4, "4")]
[TestCase(5, "5")]
public void Test_FindById(int id, string expected)
{
var table = new MyTable();
var value = table.FindById(id).Value;
Assert.AreEqual(expected, value);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment