如何在另一个列表中找到一个列表的位置?

时间:2019-05-27 04:24:36

标签: c# list compare

我正在处理两个列表。第一个包含大量字符串。第二个包含较小的字符串列表。我需要找到第二个列表在第一个列表中的位置。

我进行了枚举,由于数据量很大,这非常慢,我希望能有一个更快的方法。

        guild.createChannel('new-channel', 'text',
          permissionOverwrites[
            {
                id: guild.defaultRole.id,
                deny: ['VIEW_CHANNEL']
            },
            {
                id: user.id,
                allow: ['VIEW_CHANNEL']
            }
        ]);
    }

我需要x等于2。

4 个答案:

答案 0 :(得分:1)

好吧,这是我的旧循环循环的变种:

private int SomeMagic(IEnumerable<string> source, IEnumerable<string> target)
{
    /* Some obvious checks for `source` and `target` lenght / nullity are ommited */

    // searched pattern
    var pattern = target.ToArray();
    // candidates in form `candidate index` -> `checked length`
    var candidates = new Dictionary<int, int>();
    // iteration index
    var index = 0;

    // so, lets the magic begin
    foreach (var value in source)
    {
        // check candidates
        foreach (var candidate in candidates.Keys.ToArray()) // <- we are going to change this collection
        {
            var checkedLength = candidates[candidate];
            if (value == pattern[checkedLength]) // <- here `checkedLength` is used in sense `nextPositionToCheck`
            {
                // candidate has match next value
                checkedLength += 1;
                // check if we are done here
                if (checkedLength == pattern.Length) return candidate; // <- exit point
                candidates[candidate] = checkedLength;
            }
            else
                // candidate has failed
                candidates.Remove(candidate);
        }

        // check for new candidate
        if (value == pattern[0])
            candidates.Add(index, 1);
        index++;
    }

    // we did everything we could
    return -1;
}

我们使用候选人字典来处理以下情况:

var first = new List<string> { "AAA","BBB","CCC","CCC","CCC","CCC","EEE","FFF" };
var second = new List<string> { "CCC","CCC","CCC","EEE" };

答案 1 :(得分:1)

如果您愿意使用MoreLinq,请考虑使用public class MyFragment extends Fragment { @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); // This callback will only be called when MyFragment is at least Started. OnBackPressedCallback callback = new OnBackPressedCallback(true /* enabled by default */) { @Override public void handleOnBackPressed() { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setTitle("Save Or Not"); builder.setMessage("Do you want to save this? "); builder.setPositiveButton("Save", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // Save your content save(); // Then pop NavHostFragment.findNavController(MyFragment.this).popBackStack(); } builder.setNegativeButton("Discard",null); builder.show(); }); } }); requireActivity().getOnBackPressedDispatcher().addCallback(this, callback); } }

Window

var windows = first.Window(second.Count); var result = windows .Select((subset, index) => new { subset, index = (int?)index }) .Where(z => Enumerable.SequenceEqual(second, z.subset)) .Select(z => z.index) .FirstOrDefault(); Console.WriteLine(result); Console.ReadLine(); 将使您可以分块查看数据的“切片”(基于Window列表的长度)。然后可以使用second来查看切片是否等于SequenceEqual。如果是,则可以返回second。如果找不到匹配项,则会返回index

答案 2 :(得分:0)

采用如下所示的SomeMagic方法,如果找不到匹配项,则返回-1,否则将返回第一个列表中起始元素的索引。

private int SomeMagic(List<string> first, List<string> second)
{
    if (first.Count < second.Count)
    {
        return -1;
    }

    for (int i = 0; i <= first.Count - second.Count; i++)
    {
        List<string> partialFirst = first.GetRange(i, second.Count);
        if (Enumerable.SequenceEqual(partialFirst, second))
            return i;
    }

    return -1;
}

答案 3 :(得分:-1)

您可以使用命名空间System.Linq

使用相交扩展方法
var CommonList = Listfirst.Intersect(Listsecond)