2017-02-22 41 views
1

下面是我的模型:獲取不適當的排名,同時合併和安排2列表

public class Test 
{ 
    public int TestId { get; set; } 
    public List<VariantsRank> VariantsRanks { get; set; } 
} 

public class VariantsRank 
{ 
    public int VariantId { get; set; } 
    public string Name { get; set; } 
    public int Rank { get; set; } 
} 

我有現成的Test實例,它包含VariantsRanks

VariantId = 10, Name = "V1", Rank = 0 
VariantId = 11, Name = "V2", Rank = 1 

以下值然後我需要合併以下VariantsRank

VariantId = 12, Name = "V3", Rank = 0 
VariantId = 13, Name = "V4", Rank = 1 

並增加Rank產生以下輸出

VariantId = 10, Name = "V1", Rank = 0 
VariantId = 11, Name = "V2", Rank = 1 
VariantId = 12, Name = "V3", Rank = 2 
VariantId = 13, Name = "V4", Rank = 3 

我用下面的代碼工作正常(List1是原來的列表,List2是列表被合併)

int highestOrder = (List1.VariantsRanks.Max(cpo => cpo.Rank)) + 1; 
foreach (var rank in List2.VariantsRanks) 
{ 
    var match = List1.VariantsRanks.FirstOrDefault(x => x.VariantId == rank.VariantId); 
    if (match != null) // found 
    { 
     match.Rank = rank.Rank; 
    } 
    else 
    { 
     rank.Rank = highestOrder; 
     highestOrder = highestOrder + 1; 
     List1.VariantsRanks.Add(rank); 
    } 
} 

我那麼需要將以下VariantsRank合併到新列表中(請注意匹配的VariantId值,但它們的順序相反)

VariantId = 13, Name = "V4", Rank = 0 
VariantId = 12, Name = "V3", Rank = 1 

從而使輸出應該是

VariantId = 10, Name = "V1", Rank = 0 
VariantId = 11, Name = "V2", Rank = 1 
VariantId = 13, Name = "V4", Rank = 2 
VariantId = 12, Name = "V3", Rank = 3 

但是上面的代碼,而不是輸出

VariantId = 10, Name = "V1", Rank = 0 
VariantId = 11, Name = "V2", Rank = 1 
VariantId = 12, Name = "V3", Rank = 1 
VariantId = 13, Name = "V4", Rank = 0 

Rank值不正確地遞增

如何修改代碼,以確保未添加重複的VariantId,但增加了Rank

+0

您的代碼需要在問題中,而不是鏈接到小提琴 –

+0

@StephenMuecke:實際上,這將增加我的問題的長度和提供小提琴的原因,因爲它可以很容易地直接看到輸出並直接使用Enigmativity指出的代碼。長問題沒有引起注意 –

+0

將現有代碼縮減爲每個列表2個項目並顯示代碼在哪裏操作列表 - 這是重要的(並且小提琴甚至不工作 - 它的超時) –

回答

1

問題是在2合併中,您的添加項目的值與現有列表中的VariantId匹配。這意味着您點擊if區塊中的代碼,該代碼將現有項目的值重置爲您發佈模型中的Rank的值。

例如,在循環的第一次迭代,matchVariantID = 13現有項和您的集及其Rank等於的rank.Rank,它的數值是0

您需要先刪除現有列表中的所有匹配項,然後遍歷發佈的值,更新它們的Rank並添加到集合中。基於聊天的第二列表可能包含需要在第一個列表的中間插入項目註釋

你的代碼應該是

// Get the VariantId values of the list to be merged 
var ids = List2.VariantsRanks.Select(x => x.VariantId); 
// Remove any matches from the existing list 
List1.VariantsRanks.RemoveAll(x => ids.Contains(x.VariantId)); 
// Calculate the current highest rank 
int highestOrder = (List1.VariantsRanks.Max(x => x.Rank)); 
foreach (var rank in List2.VariantsRanks) 
{ 
    // Update the rank 
    rank.Rank = ++highestOrder; // pre-increment 
    // Add to the existing list 
    List1.VariantsRanks.Add(rank); 
} 

,那麼代碼需要是

// Get the VariantId's of the first and last items in the list to be merged 
var firstID = List2.VariantsRanks.First().VariantId; 
var lastID = List2.VariantsRanks.Last().VariantId; 
// Get the indexers of those items in the original list 
var firstIndex = List1.VariantsRanks.FindIndex(x => x.VariantId == firstID); 
var lastIndex = List1.VariantsRanks.FindIndex(x => x.VariantId == lastID); 
if (firstIndex > lastIndex) // in case they are in descending order 
{ 
    var temp = lastIndex; 
    lastIndex = firstIndex; 
    firstIndex = temp; 
} 
// Remove matches from the original list 
for (int i = firstIndex; i < lastIndex + 1; i++) 
{ 
    List1.VariantsRanks.RemoveAt(firstIndex); 
} 
// Inset the items from the list to be merged 
for(int i = 0; i < List2.VariantsRanks.Count; i++) 
{ 
    List1.VariantsRanks.Insert(firstIndex + i, List2.VariantsRanks[i]); 
} 
/Re-number the Rank 
for(int i = 0; i < List1.VariantsRanks.Count; i++) 
{ 
    List1.VariantsRanks[i].Rank = i; 
} 

注意,上面如果VariantId在合併列表中的值是連續(升序或降序)只會工作