将单个阵列与多个不同的阵列进行比较

本文关键字:阵列 比较 单个 | 更新日期: 2023-09-27 18:04:49

对于processor affinity上的一个小项目,我想创建一个更简单的方法,而不仅仅是一堆if(lvProcessors.Items[0].Checked == true && lvProcessors.Items[1] == true etc)比较它们的确切值,以查看哪些代码需要传输到(IntPtr)

为了使代码更加高效,我想将一个包含booleans的数组与至少14个其他包含booleans的数组进行比较。

示例代码:

        var CheckState = new[] { lvProcessors.Items[0].Checked, lvProcessors.Items[1].Checked, lvProcessors.Items[2].Checked, lvProcessors.Items[3].Checked };
        //setcore1 == 1, setcore2 == 2, etc
        var SetCore1 = new[] { true, false,false,false };
        var SetCore2 = new[] { true, true, false, false };
        var SetCore3 = new[] { false, true, false, false };
        var SetCore4 = new[] { true, false, true, false };
        var SetCore5 = new[] { false, true, true, false };
        var SetCore6 = new[] { true, true, true, false };
        var SetCore7 = new[] { false, false, false, true };
        var SetCore8 = new[] { true, false, false, true };
        var SetCore9 = new[] { false, true, false, true };
        var SetCore10 = new[] { true, true, false, true };
        var SetCore11 = new[] { false, false, true, true };
        var SetCore12 = new[] { true, false, true, true };
        var SetCore13 = new[] { false, true, true, true };
        var SetCore14 = new[] { true, true, true, true };
        int switchcounter = 1;
        switch (switchcounter)
        {
            case 15:
                break;
            default:
                if (Enumerable.SequenceEqual(CheckState,<insertdynamicarrayname))
                {
                    AffinityState = (IntPtr)switchcounter;
                }
                else
                {
                    switchcounter++;
                    goto default;
                }
                break;
        }

因此,如果检查了listview lvProcessors中的第一个checkbox,则var CheckState将生成包含{ true, false,false,false } 的阵列

这反过来必须与SetCore阵列中的一个进行比较,并且在这种情况下将导致与SetCore1匹配。

所以我想知道的是;我如何创建一个动态数组,基于代码上的switchcounter,它将融合"SetCore"switchcounter.ToString(),从而创建SetCore1, SetCore2, SetCore3, etc

[编辑]

正如@Luaan所建议的,我已经将他的代码实现为我想要的样子:

        var SetCore1 = new[] { true, false, false, false};
        [..]
        var SetCore15 = new[] { true, true, true, true };
        var allSets = new [] { SetCore1, SetCore2, SetCore3,SetCore4,SetCore5,SetCore6,SetCore7,SetCore8,SetCore9,SetCore10,SetCore11,SetCore12,SetCore13,SetCore14,SetCore15 };
        foreach (var set in allSets)
        {
            MessageBox.Show(counter.ToString());
            if (Enumerable.SequenceEqual(set, CheckState))
            {
                AffinityState = (IntPtr)counter;
                break;
            }
            else if (Enumerable.SequenceEqual(set, CheckState) == false) 
            {
                counter++;
            }
        }
        EditProcess.ProcessorAffinity = (IntPtr)AffinityState;

在该代码中,根据listviewcheckboxes的输入,它将把依赖的结果与SetCore匹配,并且使用counter,它将给出在foreach循环结束时转换的正确的int,并设置非常特定的核(即1、2或0、2、3等(用于在代码中较早选择的所选process(不可见(。

感谢您对比特掩码的建议,它们看起来很有用,但目前我不知道如何在不拆开一半应用程序的情况下实现它们。

将单个阵列与多个不同的阵列进行比较

只需制作一个数组:

var allSets = new [][] { SetCore1, SetCore2, SetCore3, ... }

然后你可以使用一个简单的循环:

for (var i = 0; i < allSets.Length; i++)
   HandleSet(allSets[i]);

使用Enumerable.SequenceEqual会有点慢。如果你关心性能(我认为在这种情况下你不一定这么做(,看看BitArray——它的内存要小得多,匹配主要是一个简单的位掩码。

编辑:

如果你想在bool[]int(或者byte,无论你需要什么(之间转换,你可以使用这样的东西:

public bool[] ToBoolArray(int val)
{
  var bits = new bool[sizeof(int) * 8];
  for (var i = 0; i < bits.Length; i++)
  {
    bits[i] = (val & (1 << i)) > 0;
  }
  return bits;
}
public int ToInt32(bool[] bits)
{
  var output = default(int);
  for (var i = 0; i < bits.Length; i++)
  {
    output |= bits[i] ? 1 << i : 0;
  }
  return output;
}

这样就避免了处理大量烦人的字符串。使用BitArray更简单——从int创建BitArray很简单(有一个构造函数(,并且可以很容易地将其更改回int,只需使用bits.Get(i)而不是bits[i]

或者更好的是,制作自己的类来处理这个问题:

public sealed class CpuMask
{
  private int _bits;
  public bool this[int index]
  {
    get { return (_bits & (1 << index)) > 0; }
    set { if (value) _bits |= (1 << index); else _bits &= ~(1 << index); }
  }
  public CpuMask(int mask)
  {
    _bits = mask;
  }
  public CpuMask(IntPtr mask) : this(mask.ToInt32()) { }
  public IntPtr ToIntPtr() { return new IntPtr(_bits); }
}