[英]Find Closest Keys In KeyValuePair (C#)
我試圖找到與現有字典相比在順序上最接近的一組元素。 目標是采用包含特定順序的字符串值的第一組元素。 就我而言,我可能有一個更大的列表,看起來像這樣:
{1, "ISO"}
{2, "AEA"}
...
{256, "OI"}
...
{302, "OI"}
{303, "N2"}
{304, "N2.5"}
...
{400, "N2"}
其目的是找到包含特定順序值的鍵值對,並從這些鍵值對中返回LOWEST鍵。 為了使我感到半途而廢,我提取了包含值“ OI”,“ N2”和“ N2.5”的線對的所有可能性。
假設我有一個Dictionary,它的構建如下:
Dictionary map = new Dictionary<int,string>();
map.Add(new KeyValuePair<int, string>(256, "OI");
map.Add(new KeyValuePair<int, string>(302, "OI");
map.Add(new KeyValuePair<int, string>(303, "N2");
map.Add(new KeyValuePair<int, string>(304, "N2.5");
map.Add(new KeyValuePair<int, string>(400, "N2");
我想從此Dictionary中拉出最接近其鍵的元素,以便以升序獲得列表,例如包含302、303和304作為鍵的KeyValuePairs。 最好的方法是什么?
然后我們去:
Dictionary<int, string> map = new Dictionary<int, string>();
map.Add(256, "OI");
map.Add(302, "OI");
map.Add(303, "N2");
map.Add(304, "N2.5");
map.Add(400, "N2");
var minDiffGroup = map.SelectMany(item1 =>
map
.Where(item2 => !object.Equals(item1, item2))
.Select(item2 => new { Diff = Math.Abs(item1.Key - item2.Key), Item1 = item1, Item2 = item2 })
)
.GroupBy(item => item.Diff)
.OrderBy(group => group.Key)
.FirstOrDefault();
Console.WriteLine("Diff: {0}", minDiffGroup.Key);
foreach (var item in minDiffGroup)
Console.WriteLine("Item 1: {0}\tItem 2:{1}", item.Item1, item.Item2);
Console.ReadKey();
輸出:
Diff: 1
Item 1: [302, OI] Item 2:[303, N2]
Item 1: [303, N2] Item 2:[302, OI]
Item 1: [303, N2] Item 2:[304, N2.5]
Item 1: [304, N2.5] Item 2:[303, N2]
我會進一步幫助您,但是您的問題非常模糊。
編輯
好的,在您添加了更多信息之后,我更改了lamda表達式:
Dictionary<int, string> map = new Dictionary<int, string>();
map.Add(256, "OI");
map.Add(302, "OI");
map.Add(303, "N2");
map.Add(304, "N2.5");
map.Add(400, "N2");
var orderedMap = map.OrderBy(item => item.Key); // Order the map
var minDiffGroup = orderedMap.SelectMany(item1 =>
orderedMap
.SkipWhile(item2 => !object.Equals(item1, item2)) //skip all elements which were already merged
.Skip(1) //skip item1 == item2
.Select(item2 => new { Diff = Math.Abs(item1.Key - item2.Key), Item1 = item1, Item2 = item2 }) //create an unknown type with Key = diff and both items
)
.GroupBy(item => item.Diff) //group by Diff
.OrderBy(group => group.Key) //order by Diff
.FirstOrDefault(); //Take the smallest group
if (minDiffGroup?.Count() > 0)
{
var lowestChain = minDiffGroup
.OrderBy(item => item.Item1.Key) //order by the key of item1
.TakeWhile(item => item.Item1.Key + minDiffGroup.Key == item.Item2.Key) //take all items as long as the next item has the difference of this group (otherwise there is a gap)
.SelectMany(item => new List<KeyValuePair<int, string>>() { item.Item1, item.Item2 }) //select all collected KeyValuePairs
.Distinct(); //take every once
foreach (var item in lowestChain)
{
Console.WriteLine(item);
}
}
輸出:
[302, OI]
[303, N2]
[304, N2.5]
如果您想同時從中學習,這里是一個基本的快速版本,帶有詳細說明。
總體邏輯是選擇第一個項目,保持迭代直到不再是一個序列。 然后檢查是否至少迭代了2個連續數字(如果可以,請保留並繼續嘗試下一個可用的數字,直到所有數字都被迭代為止)。
Dictionary<int, string> map = new Dictionary<int, string>();
map.Add(256, "OI");
map.Add(302, "OI");
map.Add(303, "N2");
map.Add(304, "N2.5");
map.Add(400, "N2");
// will contain the final results.
Dictionary<int, string> results = new Dictionary<int, string>();
// get map ordered
var mapList = map.OrderBy(o => o.Key).ToList();
// iterate until we have worked out each values
while (mapList.Any())
{
// take first item
var item = mapList[0];
// kepp the index of found consecutive values
var index = 0;
// loop for each value
for (int i = 1; i < mapList.Count; i++)
{
// if the value isn't 1 higher get out the loop
if (mapList[i].Key != mapList[index].Key + 1)
{
break;
}
else
{
// value is more than 1 so keep going until we can't
index++;
}
}
// if we have found at least 2 consecutive numbers
if (index > 0)
{
// add the first of the sequence
results.Add(item.Key, item.Value);
// add the rest of the sequence that was found
for (int i = 0; i < index; i++)
{
results.Add(mapList[i + 1].Key, mapList[i + 1].Value);
}
// finally removed all items found plus the starting item (hence the + 1)
mapList.RemoveRange(0, index + 1);
}
else
{
// no consecutive numbers found so just remove the item so we can loop and try the next one
mapList.RemoveAt(0);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.