我有一个看起来像这样的列表:
public static void main {
int itemToBeSearched = 4;
List<Item> list = new List<Item>();
list.Add(new Item { Id = 1, Name = "name1" });
list.Add(new Item { Id = 2, Name = "name2" });
list.Add(new Item { Id = 3, Name = "name1" });
list.Add(new Item { Id = 4, Name = "name1" });
list.Add(new Item { Id = 5, Name = "name1" });
list.Add(new Item { Id = 6, Name = "name3" });
list.Add(new Item { Id = 7, Name = "name1" });
//I need help in getting a return here
var subList = GetAdjacentList(list, itemToBeSearched);
}
public List<Item> GetAdjacentList(List list, int itemToBeSearched)
{
//Need help with the logic or linq here that would give a return such as
return List<Item> list = new List<Item>();
list.Add(new Item { Id = 3, Name = "name1" });
list.Add(new Item { Id = 4, Name = "name1" });
list.Add(new Item { Id = 5, Name = "name1" });
}
所需的输出应该是:仅包含Item2, Item3
和Item4
的子列表。
我只希望返回仅包含Item3, Item4
和Item5
的子列表,因为它们与 相邻 > 相同的名称,即name1
。
Item1
和Item7
的名称不为name1
,但由于它们不靠近相邻的组,因此不包括在内。
有人可以用Linq或其他方式帮助我解决此问题吗?
答案 0 :(得分:2)
可能有一种更简单的方法,但我想出了这一点。它不使用任何LINQ,但可以维护列表项的顺序(假设这很重要)。
public static List<Item> GetAdjacentList(List<Item> list, int itemToBeSearched)
{
List<Item> result = new List<Item>();
// find the index of the item we're searching for
int itemIdx = list.FindIndex(i => i.Id == itemToBeSearched);
if (itemIdx == -1)
{
return result; // not found, return empty list
}
// store the item for comparisons
Item item = list[itemIdx];
// loop backwards starting from the current item ann going to the 0th element
for (int i = itemIdx; i >= 0; --i)
{
// if this item is the search item, or the name matches, add it to the list
if (i == itemIdx || list[i].Name == item.Name)
{
result.Add(list[i]);
}
else
{
// exit the loop as we've run out of items with the same name
break;
}
}
if (result.Count > 0)
{
result.Reverse(); // we've added items in reverse order, so reverse the list
}
// loop through all the items from the next item to the end of the list
for (int i = itemIdx + 1; i < list.Count; ++i)
{
// if the name matches add it to the result list
if (list[i].Name == item.Name)
{
result.Add(list[i]);
}
else
{
// we've reached the end of matching names so break
break;
}
}
// return the result
return result;
}
答案 1 :(得分:1)
您没有提到当有两组连续的ID时会发生什么。例如,
案例1 :检索为两个单独的组
假设您想将两个组的岛作为单独的集合进行检索,则可以按以下方式修改方法。
public IEnumerable<IEnumerable<Item>> GetAdjacentList(List<Item> list, int itemToBeSearched)
{
var nameToBeSearched = list.First(x=>x.Id==itemToBeSearched).Name;
return list.Where(x=>x.Name.Equals(nameToBeSearched))
.GroupWhile((x, y) => y.Id - x.Id == 1)
.Where(x=>x.Count()>1);
}
GroupWhile
被定义为
public static class Extensions
{
public static IEnumerable<IEnumerable<T>> GroupWhile<T>(this IEnumerable<T> seq, Func<T,T,bool> condition)
{
T prev = seq.First();
List<T> list = new List<T>() { prev };
foreach(T item in seq.Skip(1))
{
if(condition(prev,item)==false)
{
yield return list;
list = new List<T>();
}
list.Add(item);
prev = item;
}
yield return list;
}
}
输出
案例2 :作为单个合并组检索
如果要将两个岛组合并为一个,则可以将上述方法修改为
public IEnumerable<Item> GetAdjacentList(List<Item> list, int itemToBeSearched)
{
var nameToBeSearched = list.First(x=>x.Id==itemToBeSearched).Name;
return list.Where(x=>x.Name.Equals(nameToBeSearched))
.GroupWhile((x, y) => y.Id - x.Id == 1)
.Where(x=>x.Count()>1).SelectMany(x=>x);
}
输出
答案 2 :(得分:0)
您可以使用简单的向后和向前循环在给定范围内查找具有特定名称的相邻项目,并返回与项目相同顺序的List<Item>
:
public List<Item> GetAdjacentList(List<Item> list, int itemToBeSearched, int range)
{
var result = new List<Item>();
var tar = list.FirstOrDefault(x => x.Id == itemToBeSearched);
if (tar == null) return result;
var indx = list.IndexOf(tar);
for (var i = indx - 1; i >= (indx - range); i--)
{
if (i >= 0 && list[i].Name.Equals(tar.Name,
StringComparison.CurrentCultureIgnoreCase))
result.Insert(0, list[i]);
else
break;
}
result.Add(list[indx]);
for (var i = indx + 1; i <= (indx + range) ; i++)
{
if (i < list.Count() && list[i].Name.Equals(tar.Name,
StringComparison.CurrentCultureIgnoreCase))
result.Add(list[i]);
else
break;
}
return result;
}
给定的List<Item>
示例(rang = 1
)的输出:
The adjacent items of ID 1 => 1 (name1)
The adjacent items of ID 2 => 2 (name2)
The adjacent items of ID 3 => 3, 4 (name1)
The adjacent items of ID 4 => 3, 4, 5 (name1)
The adjacent items of ID 5 => 4, 5 (name1)
The adjacent items of ID 6 => 6 (name3)
The adjacent items of ID 7 => 7 (name1)