簡體   English   中英

使用 C# 比較兩個列表並刪除缺失的數字

[英]comparing two lists and removing missing numbers with C#

有兩個列表:

List<int> list2 = new List<int>(new[] { 1, 2, 3, 5, 6 }); // missing: 0 and 4
List<int> list1 = new List<int>(new[] { 0, 1, 2, 3, 4, 5, 6 });

你如何比較兩個列表,找到 List1 中缺失的數字並將這些數字從 List1 中刪除? 更准確地說,我需要找到一種方法來指定開始和結束 position 以進行比較。

我想這個過程應該與此非常相似:

步驟1。

int start_num = 3; // we know that comparisons starts at number 3
int start = list2.IndexOf(start_num); // we get index of Number (3)
int end = start + 2; // get ending position
int end_num = list2[end]; // get ending number (6)

現在我們在 List2 (3,5,6) 中得到了用於比較的數字位置(和數字本身)

第 2 步。要獲取數字在 List1 中的位置以進行比較 - 我們可以執行以下操作:

int startlist1 = list1.IndexOf(start_num); // starting position
int endlist1 = list1.IndexOf(end_num); // ending position

范圍如下:(3,4,5,6)

步驟 3. 比較。 棘手的部分從這里開始,我需要幫助

基本上現在我們需要比較 list2 在 (3,5,6) 和 list1 在 (3,4,5,6)。 缺少的數字是“4”。

// I have troubles with this step but the result will be:

int remove_it = 4; // or int []

第四步,去除奇數。

int remove_it = 4;
list1 = list1.Where(a => a != remove_it).ToList();

效果很好,但是如果我們缺少 2 個數字會怎樣? IE

int remove_it = 4 // becomes int[] remove_it = {4, 0}

結果正如您所猜到的,結果是新的 List1,其中沒有數字 4。

richTextBox1.Text = "" + string.Join(",", list1.ToArray()); // output: 0,1,2,3,5,6

textBox1.Text = "" + start + " " + start_num; // output: 2 3
textBox3.Text = "" + end + " " + end_num; // output: 4 6

textBox2.Text = "" + startlist1; // output: 3
textBox4.Text = "" + endlist1; // output: 6

你們能幫我解決第 3 步或指出正確的方向嗎?

另外,你能說如果起始號碼(start_num)是最后一個號碼會發生什么,但我需要得到接下來的兩個號碼嗎? 在上面的示例中,數字是3,5,6,但它們應該與5,6,06,0,10,1,2沒有區別。

只回答第一部分:

 var list3 = list1.Intersect(list2);

這會將list3設置為{ 0, 1, 2, 3, 4, 5, 6 } - { 0, 4 } = { 1, 2, 3, 5, 6 }

以及對第 1 步的反應:

int start_num = 3; // 我們知道比較從數字 3 開始
int start = list2.IndexOf(start_num); // 我們得到 Number (3) 的索引
int 結束 = 開始 + 2; // 得到結尾 position

你從哪里得到所有這些神奇的數字 (3, + 2 )?

我認為你想得太多了。

var result = list1.Intersect(list2)

如果你真的需要結果是一個列表,你可以在最后添加一個.ToList

        List<int> list2 = new List<int>(new[] { 1, 2, 3, 5, 6 }); // missing: 0 and 4 
        List<int> list1 = new List<int>(new[] { 0, 1, 2, 3, 4, 5, 6 });

        // find items in list 2 notin 1
        var exceptions = list1.Except(list2);

        // or are you really wanting to do a union? (unique numbers in both arrays)
        var uniquenumberlist = list1.Union(list2);

        // or are you wanting to find common numbers in both arrays
        var commonnumberslist = list1.Intersect(list2);

也許您應該使用 OrderedList 而不是 List...

像這樣:

list1.RemoveAll(l=> !list2.Contains(l));

您可以將IntersectSkipTake結合使用,以獲得與范圍相結合的交集邏輯(此處我們忽略缺少 0 的事實,因為我們跳過它):

static void Main(string[] args)
{
    var list1 = new List<int> { 1, 2, 3, 4, 5 };
    var list2 = new List<int> { 0, 1, 2, 3, 5, 6 };

    foreach (var i in list2.Skip(3).Take(3).Intersect(list1))
        Console.WriteLine(i); // Outputs 3 then 5.

    Console.Read();
}

雖然如果我真的很誠實,我不確定被問到什么 - 我唯一確定的是相交部分:

var list1 = new List<int> { 1, 2, 3, 4, 5 };
var list2 = new List<int> { 0, 1, 2, 3, 5, 6 };

foreach (var i in list2.Intersect(list1))
    Console.WriteLine(i); // Outputs 1, 2, 3, 5.

要獲取list1中存在但list2中不存在的數字,您可以使用Except擴展方法:

IEnumerable<int> missing = list1.Except(list2);

要遍歷此結果以將它們從list1中刪除,您必須實現結果,否則它會在您更改列表時從列表中讀取,並且您會得到一個異常:

List<int> missing = list1.Except(list2).ToList();

現在你可以刪除它們:

foreach (int number in missing) {
  list1.Remove(number);
}

我不確定我是否理解您的問題,希望我給您的解決方案對您有好處。

你有 2 個列表:

列表 list2 = new List(new[] { 1, 2, 3, 5, 6 }); // 缺少:0 和 4 List list1 = new List(new[] { 0, 1, 2, 3, 4, 5, 6 });

要從 list1 中刪除 list2 中所有缺失的數字,我建議采用以下解決方案:Build a new list with missing numbers:

列表差異=新列表();

然后將您需要刪除的所有號碼放入此列表中。 現在刪除過程應該很簡單了,只需取出您在 diff 中添加的所有元素並從 list2 中刪除即可。

我是否正確理解算法是:1) 取列表 2 中的第一個數字並在列表 1 中找到該數字,2) 然后從列表 1 中刪除所有內容,直到找到列表 2 (5) 中的第二個數字 3) 重復步驟 2) 獲取下一個數字在列表 2 中。

好的,看來我沒有很好地解釋問題,對此感到抱歉。 有興趣的可以看看這段代碼就明白我的意思了:

        List<int> list2 = new List<int>() { 1, 2, 3, 5, 6 }; // missing: 0 and 4
        List<int> list1 = new List<int>() { 0, 1, 2, 3, 4, 5, 6 };

        int number = 3; // starting position

        int indexer = list2.BinarySearch(number);
        if (indexer < 0)
        {
            list2.Insert(~index, number); // don't look at this part
        }

        // get indexes of "starting position"
        int index1 = list1.Select((item, i) => new { Item = item, Index = i }).First(x => x.Item == number).Index;
        int index2 = list2.Select((item, i) => new { Item = item, Index = i }).First(x => x.Item == number).Index;

        // reorder lists starting at "starting position"
        List<int> reorderedList1 = list1.Skip(index1).Concat(list1.Take(index1)).ToList(); //main big
        List<int> reorderedList2 = list2.Skip(index2).Concat(list2.Take(index2)).ToList(); // main small


        int end = 2; // get ending position: 2 numbers to the right
        int end_num = reorderedList2[end]; // get ending number

        int endlist1 = reorderedList1.IndexOf(end_num); // ending position

        //get lists for comparison
        reorderedList2 = reorderedList2.Take(end + 1).ToList();
        reorderedList1 = reorderedList1.Take(endlist1 + 1).ToList();

        //compare lists
        var list3 = reorderedList1.Except(reorderedList2).ToList();
        if (list3.Count != 0)
        {
            foreach (int item in list3)
            {
                list1 = list1.Where(x => x != item).ToList(); // remove from list
            }
        }
        // list1 is the result that I wanted to see

如果有任何方法可以優化此代碼,請通知我。 干杯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM