linq 根据另一个数组中指定的索引从数组中选择元素c#

4smxwvx5  于 2023-05-20  发布在  C#
关注(0)|答案(2)|浏览(123)

假设我们有一个包含数据的数组:

double[] x = new double[N] {x_1, ..., x_N};

以及大小为N的数组,其中包含与x的元素相对应的标签:

int[] ind = new int[N] {i_1, ..., i_N};

根据ind,从x中选择具有特定标签I的所有元素的最快方法是什么?
比如说

x = {3, 2, 6, 2, 5}
ind = {1, 2, 1, 1, 2}
I = ind[0] = 1

结果:

y = {3, 6, 2}

显然,它可以很容易地(但不是有效和干净)完成循环,但我认为应该有办法做到这一点使用.Where和lambdas..谢谢
编辑:
MarcinJuraszek提供的答案是完全正确的,谢谢。然而,我已经简化了这个问题,希望它能在我原来的情况下工作。你能看看如果我们有泛型类型的问题是什么吗:

T1[] xn = new T1[N] {x_1, ..., x_N};
T2[] ind = new T2[N] {i_1, ..., i_N};
T2 I = ind[0]

使用提供的解决方案,我得到一个错误“委托'System.Func'不接受2个参数”:

T1[] y = xn.Where((x, idx) => ind[idx] == I).ToArray();

非常感谢

t40tm48m

t40tm48m1#

这样如何:

var xs = new[] { 3, 2, 6, 2, 5 };
var ind = new[] { 1, 2, 1, 1, 2 };
var I = 1;

var results = xs.Where((x, idx) => ind[idx] == I).ToArray();

它使用了第二个不太流行的Where重载:
Enumerable.Where<TSource>(IEnumerable<TSource>, Func<TSource, Int32, Boolean>)
它的项索引可用作 predicate 参数(在我的解决方案中称为idx)。

  • 通用版本 *
public static T1[] WhereCorresponding<T1, T2>(T1[] xs, T2[] ind) where T2 : IEquatable<T2>
{
    T2 I = ind[0];
    return xs.Where((x, idx) => ind[idx].Equals(I)).ToArray();
}
  • 用途 *
static void Main(string[] args)
{
    var xs = new[] { 3, 2, 6, 2, 5 };
    var ind = new[] { 1, 2, 1, 1, 2 };

    var results = WhereCorresponding(xs, ind);
}

通用+ double版本

public static T[] Test<T>(T[] xs, double[] ind)
{
    double I = ind[0];

    return xs.Where((x, idx) => ind[idx] == I).ToArray();
}
lrpiutwd

lrpiutwd2#

这是Enumerable.Zip的一个经典用法,它通过两个相互并行的枚举运行。使用Zip,您可以一次通过获得结果。下面的代码是完全类型不可知的,尽管我使用int s和string s进行说明:

int[] values = { 3, 2, 6, 2, 5 };
string[] labels = { "A", "B", "A", "A", "B" };
var searchLabel = "A";

var results = labels.Zip(values, (label, value) => new { label, value })
                    .Where(x => x.label == searchLabel)
                    .Select(x => x.value);

相关问题