我有一个module MyEngine
class MyEngine < Rails::Engine
config.before_initialize do
config.i18n.load_path += Dir["#{config.root}/config/locales/**/*.yml"]
end
end
end
,其中module MyEngine
class MyEngine < Rails::Engine
initializer 'MyEngine', before: :load_config_initializers do
Rails.application.config.i18n.load_path += Dir["#{config.root}/config/locales/**/*.yml"]
end
end
end
是一个$(function () {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container'
},
title: {
text: 'Step line ends prematurely'
},
series: [{
data: [[0, 1], [1, 2], [3, 4]],
name: 'Longer'
}, {
data: [[0, 2], [1, 3]],
name: 'Shorter'
}]
});
});
字段List<T>
。获取T
中任何对象中尚未使用的唯一int
值的最佳方法是什么?
此程序通常如何编码?是否有数据类型可以帮助解决这个问题,还是需要存储最大的id值?
修改
当我获得1的对象的id时,我将如何从List中删除该对象。当我创建一个新对象时,我希望唯一的id为2.在这种情况下,有没有比存储最后一个唯一ID更好的方法?
感谢。
答案 0 :(得分:1)
对于这种方法,我写了一个继承的List&lt; T&gt;它保存逻辑,因此您无需在访问列表的任何位置实现它。 如果你有一个具有Id值的最小接口,你甚至可以保持通用。
interface IWithId {
int Id { get; set; }
}
class CustomList<T> : List<T> where T : class, IWithId {
private lastUsedId = 1;
public void AddObjectWithAutomaticId(T newObject) {
newObject.Id = lastUsedId++;
base.Add(newObject);
}
public T GetElementById(int id) {
return base.SingleOrDefault(p => p.Id == id);
}
}
Remove
方法仍然可以像以前一样工作。该类存储上次使用的Id,独立于您删除的内容。当您想要添加具有给定ID的对象而不是自动填充它时,Add
方法仍然可用。
答案 1 :(得分:0)
我同意GUID适合您作为id属性的评论。但是,如果您需要使用int,那么我建议使用一个新类。
继承List<T>
的问题是您必须覆盖多个方法,以确保Add()
,AddRange()
,Insert()
之类的内容无法添加重复的ID并更新存储的最大ID。很容易错过一个。
我会使用一个不继承任何东西但在内部使用字典的类。这将不会与List<T>
具有相同的方法,但这不一定是坏事 - 它可以避免出错,并且您可以使用ToList()
方法来查询它,就好像这是一个List<T>
。
使用上一个答案的一部分来确保T
具有Id
属性:
interface IHasId {
int Id { get; set; }
}
class AutoIdList<T> where T : class, IHasId {
private readonly IDictionary<int, T> _dictionary = new Dictionary<int, T>();
//Using this list ensures you don't duplicate ids even
//for an item added with an explicit id then removed
private IList<int> _historicalIds = new List<int>();
private int highestAutoGeneratedId = 0;
public List<T> ToList() {
return _dictionary.Values.ToList();
}
public void Add(T item, bool generateId) {
if (generateId) {
highestAutoGeneratedId = NextId();
T.Id = highestAutoGeneratedId;
}
Add(T);
}
public void Replace(T item) {
_dictionary[item.Id] = item;
}
public void Remove(T item) {
_dictionary.Remove(item.Id);
}
private void Add(T item) {
if (_historicalIds.Contains(T.Id)) {
//throw an appropriate exception
} else {
_historicalIds.Add(T.Id);
_dictionary.Add(T.Id, T);
}
}
private int NextId() {
var id = highestAutoGeneratedId + 1;
while (_historicalIds.Contains(id)) {
id++;
}
return id;
}
//More methods to simulate AddRange, Insert, etc if required. Leave if not.
//Should all have simple logic but require checking of Id if adding anything
//Also need logic to maintain the list of used ids
}