简体   繁体   中英

Search the list and take item based on the index value of the match

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" },
};

Above all the list have "1" but If I search with one then it should return the 3d list because of the index, so just need to compare the index also and need to take that one.

IF I search with "7" then it should return the 2nd list.

In overall if more than one matching result then it should return the one list based on the position

IF match is there take the array IF find another match take the array in which the match has the lowest index.

How to achieve this?

You would need to split by the comma and then order by the index. Since split will return an array you would need to create a list first:

slot candidate = (from s in slots
    let parts = s.Ids.Split(',')
    where parts.Contains(searchItem)
    orderby Array.IndexOf(parts, searchItem)
    select s).FirstOrDefault();

detail: the let part allows you to save the split result temporarily in the variable parts. This way you can avoid spliting again when the order by clause is executed.

Try this approach that avoids all of the muck IndexOf or 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());

With this you get the following:

  • map["1"] gives slot { Ids = "1,4,6,5,10,11,29,40,7" }
  • map["7"] gives slot { Ids = "10,11,12,13,1,7" }

You could use

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;
            }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM