1

TL;DR バージョン:

正確に 1 つの要素 (追加要素または欠落要素のいずれか) によって異なる 2 つのリストを列挙し、他のすべての要素と一致させながら、どの要素が変更されたかを伝える方法はありますか?


私のクラスには、コンストラクターを介して注入さList<View>れたものから作成されたプロパティがあります。List<Model>それぞれがそれぞれをパブリック プロパティとしてViewラップします。Model

同じスコープ内に、次の条件でvoid Update(List<Model> newList)別のリストを受け取るルーチンがあります:前と同じで、正または負の要素が 1 つだけあります。これは、アイテムが他の場所でデータ バインドされたリストに追加または削除されるたびに が呼び出され、アプリケーションには一度に 1 つの要素を追加/削除するオプションしかないためです。ModelList<Model>Update

Update古いリストのモデル (ビューにラップされている) を単に新しいリストに置き換えるのではなく、操作の動機は、Viewクラスが状態を保存することです。とにかくモデル。

問題は次のとおりです。新しいモデルがある場合は新しいビューを追加する必要があり、それぞれのモデルが存在しない場合はそれぞれのビューを削除する必要があり、追加された要素を除いて、既存のビューを既存のモデルと一致させる必要があります。削除されました。私はそれを行う方法がわかりません。

そのため、リストの最初の要素のモデルを新しいリストの最初の要素と比較し、それらが一致する場合は 2 番目の要素に移動することを考えていました。ある時点でそれらは異なりますが、これは要素の追加が原因である可能性があり (その後、残りは 1 つのインデックスにシフトされます)、または 1 つの要素の削除が原因である可能性があります (この場合、残りは下にシフトされ、別の要素は、実際にはリスト内の既存の要素になります)。

最初の異なる要素が追加または削除によるものかどうかを判断する賢明な方法はありますか?

4

3 に答える 3

2

コード行に関しては最短の解決策ではありませんが、一度に挿入または削除できる要素が 1 つしかないことがわかっている場合(ただしリスト全体で複数の変更がある場合)、次のループを使用できます。

var i = 0;
var j = 0;

while(i < oldList.Count || j < newList.Count)
{
    if (i >= oldList.Count)
    {
        for(; j < newList.Count; j++)
        {
            Console.WriteLine("{0} added", newList[j]);
        }
        break;
    }
    if (j >= newList.Count)
    {
        for(; i < oldList.Count; i++)
        {
            Console.WriteLine("{0} removed", oldList[i]);
        }
        break;
    }

    if (oldList[i] == newList[j])
    {
        Console.WriteLine("{0} not changed", oldList[i]);
        i++;
        j++;
    }
    else if(j < (newList.Count - 1) && oldList[i] == newList[j+1])
    {
        Console.WriteLine("{0} added", newList[j]);
        j++;
    }
    else
    {
        Console.WriteLine("{0} removed", oldList[i]);
        i++;

    }
}

Exceptソリューションよりも次のような利点があると思います。

  • 複数の変更を見つけることができます
  • O(n+m) 最大複雑度
  • 変更を見つける方法に関するより多くの制御:Exceptソリューションは同等性のみをチェックできますが、ここでは、一部のモデル プロパティが変更され、他は変更されていないかどうかを確認できます。
于 2016-04-19T07:06:29.680 に答える