如果我有 2 个字符串列表:
List<string> firstList = new List<string>("010", "111", "123");
List<string> secondList = new List<string>("010", "111", "999");
如何比较列表中每个项目中的每个字符?例如:应将"0"与"0"进行比较,将"1"与"1"进行比较,将"0"与"0"进行比较,依此类推。看来我可以使用SelectMany
但我被困在如何做到这一点
编辑:
这些列表在相互比较时应返回 true(因为星号表示任何字符,我正在验证以确保每个项目的长度正好为 3 个字符)
List<string> firstList = new List<string>("010", "111", "123");
List<string> secondList = new List<string>("010", "1*1", "***");
使用通配符进行了更新
class WildcardStringComparer : IEqualityComparer<string>
{
public bool Equals(string s1, string s2)
{
if (s1.Length != s2.Length) return false;
for (int i = 0; i < s1.Length; i++)
{
if (s1[i] != s2[i] && s1[i] != '*' && s2[i] != '*')
return false;
}
return true;
}
public int GetHashCode(string obj)
{
throw new NotImplementedException();
}
}
结果:
List<string> firstList = new List<string>{"010", "111", "999"};
List<string> secondList = new List<string>{"010", "111", "999"};
bool res = firstList.SequenceEqual(secondList, new WildcardStringComparer()); // True
和
List<string> firstList = new List<string>{"010", "111", "999"};
List<string> secondList = new List<string>{"010", "111", "*99"};
bool res = firstList.SequenceEqual(secondList, new WildcardStringComparer()); // True
和
List<string> firstList = new List<string>{"010", "111", "999"};
List<string> secondList = new List<string>{"010", "111", "199"};
bool res = firstList.SequenceEqual(secondList, new WildcardStringComparer()); // False
如果您只想比较列表之间的匹配字符序列:
bool sameCharacters = Enumerable.SequenceEqual(firstList.SelectMany(x => x),
secondList.SelectMany(x => x));
这将导致true
,即对于以下两个列表 - 它们的字符序列匹配(两者"010111123"
),它们各自的字符串条目不匹配:
List<string> firstList = new List<string> {"010", "111", "123" };
List<string> secondList = new List<string> {"010", "11", "1123" };
编辑以回复评论:
对于通配符匹配,您可以使用Zip()
并比较每个字符,如果它们基于通配符条件匹配,则返回 true,然后只需检查压缩序列中的每个元素是否true
。
var isWildCardMatch = firstList.SelectMany(x => x).Zip(secondList.SelectMany( x => x), (a,b) => { if(a==b || a =='' || b == '') 返回真; 返回假;
}).All( x=> x);
上面的方法跨越了字符串条目边界,这将导致错误匹配 - 这里有一个更好的方法:
bool isWildCardMatch = firstList.Zip(secondList, (x, y) =>
{
var matchWord = y.Select((c, i) => c == '*' ? x[i] : c);
return matchWord.SequenceEqual(x);
}).All(x => x);
假设您要将第一个列表中第一个字符串的第一个字符与第二个列表中第一个字符串的第一个字符进行比较,将第一个列表中第一个字符串的第二个字符与第二个列表中第一个字符串的第二个字符进行比较,依此类推。 我可以想到两种实现。
我会从那个开始:
var firstCharList = new List<char>();
var secondCharList = new List<char>();
firstList.foreach(s =>
{
foreach(char c in s)
{
firstCharList.Add(c);
}
});
secondList.foreach(s =>
{
foreach(char c in s)
{
secondCharList.Add(c);
}
});
for(int i = 0; i < firstCharList.Length; i++)
{
if(firstCharList[i] == secondCharList[i]) yield return i;
}
这将生成一个整数列表(或数组,或其他任何内容),这些整数对应于两个字符串具有相同字符的索引。
第二个是这样的:
firstList.foreach(s =>
{
var index = firstList.IndexOf(s);
var sPrime = secondList[index];
for(int i = 0; i < s.Length; i++)
{
if(s[i] == sPrime[i]) yield return s[i];
}
}
该字符仅返回在相同索引处相等的任何字符。