我的问题是我需要比较两个列表并找到共享相同字段值的对象数量。请找一个两个列表的常用对象,或者一些连接操作。我不想使用Linq,因为我需要访问元素的索引,但是现在这些类/方法已经简化了。 Pip类:
public class Pip{
public CONTROLLER.COLORS Color;
}
简化类序列基本上是点数列表
public class Sequence{
private List<Pip> pips = new List<Pip>();
public Sequence(Pip[] pips)
{
for (int i = 0; i < pips.Length; i++)
{
addPip(pips[i]);
}
}
public List<Pip> getPips()
{
return pips;
}
}
所以现在我有这个方法,它会返回两个序列的相同颜色的点数,其中每个点都有一些颜色。
private int getMatchedColors(Sequence lockSeq, Sequence checkSeq)
{
List<Pip> lockPips = lockSeq.getPips();
List<Pip> checkPips = checkSeq.getPips();
List<Pip> excludedPips = new List<Pip>(lockPips.Count);
int matchedColors = 0;
for (int i = 0; i < lockPips.Count; i++)
for (int j = 0; j < checkPips.Count; j++)
if (checkPips[i].Color == lockPips[j].Color && !excludedPips.Contains(lockPips[j]))
{
matchedColors++;
excludedPips.Add(lockPips[j]);
break;
}
return matchedColors;
}
逻辑开始我的理由是下一个。
获取lockPips
列表的每个元素,并将当前点的颜色与checkPips
&#39;的当前颜色进行比较。列表点。如果匹配,我们会检查是否匹配lockPips
&#39;当前点已经过检查。如果没有,那么我们增加计数器并添加lockPips
&#39;当前点到checkedPips
列表,从而确保在下次检查时跳过它。
调试显示excludedPips
列表已经包含第一次检查的点,并且它在每次检查时都使用它的颜色,从而使算法跳过&#34中的所有指令;如果&#34;言。
示例:lockPips:RED,GREEN,GREEN checkPips:RED,GREEN,GREEN 预期匹配的颜色:3个实际匹配的颜色:1(红色)
lockPips:BLUE,BLUE,BLUE checkPips:预期蓝色,蓝色,红色 matchedColors:2个匹配的实际颜色:1(蓝色)
因此,任何实际matchedColors
&gt;的结果都是如此0是1。
答案 0 :(得分:1)
您不必为此目的编写自己的逻辑,因为您可以使用LINQ和Intersect
方法获得所需的结果。像这样:
List<Pip> excludedPips = lockPips.Intersect(checkPips).ToList();
同样在你班上:
public class Pip
{
public string Color { get; set; }
public override bool Equals(object obj)
{
if (!(obj is Pip))
return false;
Pip p = (Pip)obj;
return (p.Color == Color);
}
public override int GetHashCode()
{
return String.Format("{0}", Color).GetHashCode();
}
}
或者,如果您想获得两个List的常见对应元素,请使用Zip
:
List<Pip> excludedPips = lockPips.Zip(checkPips , (f,s) => f.Color == s.Color ? f : null)
.Where(c => c!= null).ToList();
答案 1 :(得分:0)
你可以做这样的事情
List<Pip> Matches = new List<Pip>(L1);
// Get the matches
Matches.AddRange(L2.Except(Matches));
Matches.RemoveAll(pip=> !L2.Contains(pip));
然后,只要你想在匹配中找到所需点子的原始索引,就可以这样做
List<int> indexes = new List<int>();
if (L1.Contains(desiredPip)) indexes = Enumerable.Range(0, L1.Count).Where(i => L1[i].Color == desiredPip.Color).ToList();
if (L2.Contains(desiredPip)) indexes = Enumerable.Range(0, L2.Count).Where(i => L2[i].Color == desiredPip.Color).ToList();
我知道你说你不想使用LINQ,但如果你唯一的理由是你想要访问索引,这就解决了这个问题。