Противоположность Intersect()
Пересечение может использоваться для поиска совпадений между двумя коллекциями, например:
// Assign two arrays.
int[] array1 = { 1, 2, 3 };
int[] array2 = { 2, 3, 4 };
// Call Intersect extension method.
var intersect = array1.Intersect(array2);
// Write intersection to screen.
foreach (int value in intersect)
{
Console.WriteLine(value); // Output: 2, 3
}
Однако, чего бы я хотел добиться, так это наоборот, я бы хотел перечислить элементы из одной коллекции, которые отсутствуют в другой:
// Assign two arrays.
int[] array1 = { 1, 2, 3 };
int[] array2 = { 2, 3, 4 };
// Call "NonIntersect" extension method.
var intersect = array1.NonIntersect(array2); // I've made up the NonIntersect method
// Write intersection to screen.
foreach (int value in intersect)
{
Console.WriteLine(value); // Output: 4
}
Ответы
Ответ 1
Как указано, если вы хотите получить 4 в результате, вы можете сделать вот так:
var nonintersect = array2.Except(array1);
Если вам требуется реальное непересечение (также и 1 и 4), то это должно сделать трюк:
var nonintersect = array1.Except(array2).Union( array2.Except(array1));
Это не будет наиболее эффективным решением, но для небольших списков оно должно работать нормально.
Ответ 2
Вы можете использовать
a.Except(b).Union(b.Except(a));
Или вы можете использовать
var difference = new HashSet(a);
difference.SymmetricExceptWith(b);
Ответ 3
Этот код перечисляет каждую последовательность только один раз и использует Select(x => x)
, чтобы скрыть результат, чтобы получить чистый метод расширения стиля Linq. Поскольку он использует HashSet<T>
, его время выполнения O(n + m)
, если хеши хорошо распределены. Дублирующие элементы в любом списке опущены.
public static IEnumerable<T> SymmetricExcept<T>(this IEnumerable<T> seq1,
IEnumerable<T> seq2)
{
HashSet<T> hashSet = new HashSet<T>(seq1);
hashSet.SymmetricExceptWith(seq2);
return hashSet.Select(x => x);
}
Ответ 4
Я думаю, что вы можете искать Except
:
Оператор Except производит набор Разница между двумя последовательностями. Это вернет только элементы в первом последовательность, которая не появляется в второй. Вы можете по желанию предоставить Ваша собственная функция сравнения равенства.
Для получения дополнительной информации просмотрите эту ссылку, эту ссылку или Google.
Ответ 5
Я не уверен на 100%, что ваш метод NonIntersect должен делать (относительно теории множеств) - это он
B\A (все из B, которое не встречается в A)?
Если да, то вы должны иметь возможность использовать операцию Except (B.Except(A)).
Ответ 6
/// <summary>
/// Given two list, compare and extract differences
/// http://stackoverflow.com/questions/5620266/the-opposite-of-intersect
/// </summary>
public class CompareList
{
/// <summary>
/// Returns list of items that are in initial but not in final list.
/// </summary>
/// <param name="listA"></param>
/// <param name="listB"></param>
/// <returns></returns>
public static IEnumerable<string> NonIntersect(
List<string> initial, List<string> final)
{
//subtracts the content of initial from final
//assumes that final.length < initial.length
return initial.Except(final);
}
/// <summary>
/// Returns the symmetric difference between the two list.
/// http://en.wikipedia.org/wiki/Symmetric_difference
/// </summary>
/// <param name="initial"></param>
/// <param name="final"></param>
/// <returns></returns>
public static IEnumerable<string> SymmetricDifference(
List<string> initial, List<string> final)
{
IEnumerable<string> setA = NonIntersect(final, initial);
IEnumerable<string> setB = NonIntersect(initial, final);
// sum and return the two set.
return setA.Concat(setB);
}
}
Ответ 7
array1.NonIntersect(массив2);
Непересекающийся такой оператор отсутствует в Linq, который вы должны делать
except → union → except
a.except(b).union(b.Except(a));
Ответ 8
string left = "411329_SOFT_MAC_GREEN";
string right= "SOFT_MAC_GREEN";
string[] l = left.Split('_');
string[] r = right.Split('_');
string[] distinctLeft = l.Distinct().ToArray();
string[] distinctRight = r.Distinct().ToArray();
var commonWord = l.Except(r, StringComparer.OrdinalIgnoreCase)
string result = String.Join("_",commonWord);
result = "411329"