使用linq避免嵌套循环

时间:2018-08-11 20:35:43

标签: c# linq

我想创建一种方法来查找两个数字之和为target的索引。

因此,我创建了此方法:

public static int[] TwoSum(int[] nums, int target)
{
    for (var i = 0; i < nums.Length; i++)
    {
        for (var j = 0; j < nums.Length; j++)
        {
            if (j == i) continue;

            if (nums[i] + nums[j] == target)
            {
                return new[] { i, j };
            }
        }
    }
}

哪个工作正常。但是,我正在尝试向自己学习一些LINQ,无法解决。我查看了各种示例,但由于使用两次相同的数组,所以最终总是陷入困境。因此,我不知道该选择什么以及如何两次访问它,同时还要确保它不会两次通过相同的索引。

从上述循环中获取LINQ的任何帮助将不胜感激。

样本数据:

var nums = new [] { 2, 7, 11, 15 };
var target = 9;

4 个答案:

答案 0 :(得分:3)

相当于LINQ的循环为:

from x in nums.Select((n, i) => new { Number = n, Index = i })
from y in nums.Select((n, i) => new { Number = n, Index = i })
where x.Index != y.Index && x.Number + y.Number == target
select new [] { x.Index, y.Index }

但这需要创建匿名类型实例,因此我想说循环版本要好得多且效率更高。

答案 1 :(得分:2)

这里使用SelectMany作为单个LINQ语句。使用LINQ,您必须颠倒思维……只需键入return,然后从那里开始。

public static int[] TwoSumWithLinq(int[] nums, int target)
{
    return nums.SelectMany
    (
        (m, i) => nums.Select
            (
                (n,j) => new { n, m, i, j }
            )
    )
    .Where
    (
        r => (r.i != r.j) && (r.m + r.n == target)
    )
    .Select
    (
        r => new int[] { r.i, r.j }
    )
    .FirstOrDefault();
}

Link to working example on DotNetFiddle

答案 2 :(得分:1)

我会选择比较干净的版本:

public static int[] TwoSum(int[] nums, int target)
{
    return
    (
        from i in Enumerable.Range(0, nums.Length)
        from j in Enumerable.Range(0, nums.Length)
        where i != j && nums[i] + nums[j] == target
        select new [] { i, j }
    ).FirstOrDefault();
 }

答案 3 :(得分:-1)

def save_complex(dataset, *args, **kwargs):
    ds = dataset.expand_dims('ReIm', axis=-1) # Add ReIm axis at the end
    ds = xarray.concat([ds.real, ds.imag], dim='ReIm')
    return ds.to_netcdf(*args, **kwargs)

def read_complex(*args, **kwargs):
    ds = xarray.open_dataset(*args, **kwargs)
    return ds.isel(ReIm=0) + 1j * ds.isel(ReIm=1)

请注意,如果数组中没有任何匹配条件的成员(成员总数=目标),该方法将返回public static int[] TwoSum(int[] nums, int target) { int[] indexes = Enumerable.Range(0, nums.Length).ToArray(); var result = from i in indexes from j in indexes where i != j && (nums[i] + nums[j]) == target select new [] { i, j }; return result.FirstOrDefault(); }