var slots = new List<slot>()
{
new slot { Ids = "2,3,4,6,8,9,1" },
new slot { Ids = "10,11,12,13,1,7" },
new slot { Ids = "1,4,6,5,10,11,29,40,7" },
};
最重要的是,列表中有"1",但如果我用一个搜索,那么由于索引的原因,它应该会返回3d列表,所以只需要比较索引,就可以了。
如果我用"7"搜索,那么它应该返回第二个列表。
总的来说,如果有多个匹配结果,那么它应该返回基于位置的一个列表
IF匹配取数组IF查找另一个匹配取匹配具有最低索引的数组。
如何做到这一点?
您需要按逗号拆分,然后按索引排序。由于split将返回一个数组,您需要首先创建一个列表:
slot candidate = (from s in slots
let parts = s.Ids.Split(',')
where parts.Contains(searchItem)
orderby Array.IndexOf(parts, searchItem)
select s).FirstOrDefault();
detail:let
部分允许您将拆分结果临时保存在可变部分中。这样可以避免在执行order by子句时再次拆分。
尝试这种方法可以避免所有的垃圾IndexOf
或Contains
:
List<slot> slots = new List<slot>()
{
new slot { Ids = "2,3,4,6,8,9,1" },
new slot { Ids = "10,11,12,13,1,7" },
new slot { Ids = "1,4,6,5,10,11,29,40,7" },
};
IEnumerable<IGrouping<string, slot>> query =
from slot in slots
let Ids = slot.Ids.Split(',')
from x in Ids.Select((number, index) => (number, index))
orderby x.index
group slot by x.number;
Dictionary<string, slot> map = query.ToDictionary(x => x.Key, x => x.First());
有了这个,你会得到以下内容:
map["1"]
给出slot { Ids = "1,4,6,5,10,11,29,40,7" }
map["7"]
给出slot { Ids = "10,11,12,13,1,7" }
您可以使用
var result = slots.Select(x=>x.Ids.Split(new[]{','}))
.Where(x=>x.Contains(itemToSearch))
.OrderBy(x=>Math.Abs((Array.IndexOf(x,itemToSearch) + 1) - Convert.ToInt32(itemToSearch)))
.Select(x=>string.Join(",",x))
.First();
private slot search(List<slot> slots, string searchItem)
{
for (int i = 0; i < slots.Count; i++)
{
var slotIds = slots[i].Ids.Split(',');
if (slotIds.contains(searchItem))
return slots[i];
}
return null;
}