C#如何将List <string []>项与下一项进行比较?

时间:2019-10-29 12:39:11

标签: c# arrays string list compare

我有一个List<string[]>,我想将列表中的 first 数组与 next 进行比较,然后打印部分。在两个字符串数组中均大于等于

例如:

public static void Main()
{
     List<string[]> list = new List<string[]>();
     string[] a = {"some", "random", "string"};
     string[] b = {"some", "other", "random", "string"};
     list.Add(a);
     list.Add(b);
     string[] difference = Compare(list);
}

public static string[] Compare (List<string[]> A)
{
     //do something here
}

最终目标是循环循环以将列表中的每个字符串数组与其他每个字符串数组进行比较。 预先感谢。

6 个答案:

答案 0 :(得分:2)

1。在列表中找到数组对的交点

private static IEnumerable<(string,string[])> Compare(List<(string Name,string[] Words)> lists)
{
    for(int i = 0; i < lists.Count - 1; i++) {
        var a = lists[i];
        var b = lists[i + 1];
        yield return ($"{a.Name}<->{b.Name}", a.Words.Intersect(b.Words).ToArray());
     }
}

测试

代码

List<(string, string[])> list = new List<(string, string[])>();
string[] a = {"some", "random", "string"};
string[] b = {"some", "other", "random", "string"};
string[] c = {"some", "other2", "random", "string2"};
list.Add(("a", a));
list.Add(("b", b));
list.Add(("c", c));

foreach( var pair in Compare(list) )
        Console.WriteLine($"{pair.Item1}: {string.Join(", ", pair.Item2)}");

输出

// .NETCoreApp,Version=v3.0
a<->b: some, random, string
b<->c: some, random

2。查找所有数组中的单词

private static string[] InAll(List<string[]> lists)
{
    var inAll = new List<string>();
    foreach(var list in lists ) {
        foreach(var word in list) {
            if(lists.All(l => l.Contains(word))) {
                inAll.Add(word);
            }
        }
    }
    return inAll.Distinct().ToArray();
}

测试

代码

public static void Main(string[] args)
{
    List<string[]> list = new List<string[]>();
    string[] a = {"some", "random", "string"};
    string[] b = {"some", "other", "random", "string"};
    string[] c = {"some", "other2", "random", "string2"};
    list.Add(a);
    list.Add(b);
    list.Add(c);

    foreach( var inAll in InAll(list) ) Console.WriteLine(inAll);
}

输出

// .NETCoreApp,Version=v3.0
some
random

答案 1 :(得分:2)

让我们在 Linq 的帮助下实现它(在一般情况下):

using System.Linq;

...

private static IEnumerable<T[]> Differences<T>(IEnumerable<IEnumerable<T>> source, 
                                               IEqualityComparer<T> comparer = null) {
  if (null == source)
    throw new ArgumentNullException(nameof(source));

  if (null == comparer)
    comparer = EqualityComparer<T>.Default;

  if (null == comparer)
    throw new ArgumentNullException(nameof(comparer), 
      $"No default comparer for {typeof(T).Name}");

  Dictionary<T, int> prior = null;

  foreach (var line in source) {
    Dictionary<T, int> current = line
      .GroupBy(item => item, comparer)
      .ToDictionary(chunk => chunk.Key, chunk => chunk.Count(), comparer);

    if (null != prior) 
      yield return current
        .Where(item => prior.ContainsKey(item.Key))
        .SelectMany(item => Enumerable
           .Repeat(item.Key, Math.Min(item.Value, prior[item.Key])))
        .ToArray();

    prior = current;
  }
}

演示:

  List<string[]> list = new List<string[]>() {
    new []  { "some", "random", "string" },
    new []  { "some", "other", "random", "string" },
    new []  { "some", "some", "some" },
    new []  { "some", "some", "other" },
    new []  { "some", "other", "some" },
  };

  string demo = string.Join(Environment.NewLine, Differences(list)
    .Select(line => string.Join(", ", line)));

  Console.Write(demo);

结果:

some, random, string  // 1st and 2nd strings
some                  // 2nd and  3d strings
some, some            //  3d and 4th strings 
some, some, other     // 4th and 5th strings

如果只想第一行,请添加.FirstOrDefault():

string demo = Differences(list)
  .Select(line => string.Join(", ", line)) 
  .FirstOrDefault();

Console.Write(demo);

结果:

some, random, string

最后,如果要与所有项(所有行中的常用项)相交:

    private static IEnumerable<T> IntersectAll<T>(IEnumerable<IEnumerable<T>> source, 
                                              IEqualityComparer<T> comparer = null) {
      if (null == source)
        throw new ArgumentNullException(nameof(source));

      if (null == comparer)
        comparer = EqualityComparer<T>.Default;

      if (null == comparer)
        throw new ArgumentNullException(nameof(comparer), 
          $"No default comparer for {typeof(T).Name}");

      Dictionary<T, int> prior = null;

      foreach (var line in source) {
        Dictionary<T, int> current = line
          .GroupBy(item => item, comparer)
          .ToDictionary(chunk => chunk.Key, chunk => chunk.Count(), comparer);

        if (null != prior)
          prior = current
            .Where(item => prior.ContainsKey(item.Key))
            .ToDictionary(item => item.Key, item => Math.Min(item.Value, prior[item.Key]));
        else
          prior = current;
      }

      return (prior ?? new Dictionary<T, int>())
        .SelectMany(item => Enumerable.Repeat(item.Key, item.Value));
    }

答案 2 :(得分:0)

要比较任意数量的列表,您可以编写如下内容:

public static string[] Compare (List<string[]> lists)
{
    var temp = lists.First().ToList();
    foreach(var l in lists)
    {
        temp = temp.Intersect(l).ToList();
    }
    return temp.ToArray();
}

这将导致

some
random
string

当然,如果列表为空,您将添加错误处理,等等。

答案 3 :(得分:0)

public static string[] Compare(List<string[]> A)
{
    string result = string.Empty;
    foreach(string s in A[0])
    {
        if(A[1].Contains(s))
        {
            if(result==string.Empty)
            {
                result += s;
            }
            else
            {
                result += "," + s;
            }
        }
    }

    return result.Split(',');

}

答案 4 :(得分:0)

似乎您只需要所有数组的交集即可:

private static string[] GetCommonElements(List<string[]> list)
{
    if (!list.Any())
    {
        return Array.Empty<string>();
    }

    IEnumerable<string> result = list[0];

    foreach (string[] collection in list.Skip(1))
    {
        result = result.Intersect(collection);
    }

    return result.ToArray();
}

答案 5 :(得分:0)

我个人尝试使用 linq 解决问题,希望下面的代码可以回答您的问题。

结果:

Result Of Code

    public static IEnumerable<string> Compare(List<string[]> items)
    {
        var liste = new List<string>() ;
        AddingElements(items, liste);
        return liste.Distinct();
    }

    private static void AddingElements(List<string[]> items, List<string> liste)
    {
        items.Skip(1).ToList().ForEach((e) =>
        {
            liste.AddRange(e.Difference(items.First()));
        });
    }

    public static string[] Difference(this string[] sourceArray, string[] stringArray)
    {
        return sourceArray.Where(e => stringArray.Contains(e))
                          .ToArray();
    }