这是我的问题。我有一个特定的列表,为了简单起见,我将其作为int[]
呈现。
int[] a = {1,2,3,4,5};
假设我需要转换此列表中的每个项目,但根据具体情况,我可能会返回一个int或一组int。
例如,如果值奇数,则需要返回{v}
;如果值偶数,则需要返回{v,v+1}
。我做到了这一点:
int[] b = a.SelectMany(v => v % 2 == 0 ? new int[] { v, v+1 } : new int[] { v })
.ToArray();
所以如果我运行它,我会得到预期的响应:
{1,2,3,3,4,5,5}
看到我有重复的数字,对吗? 3
和5
。我不想要那些重复的数字。现在,您可以告诉我,我可以在处理数组后调用.Distinct()
。
这就是问题所在。 SelectMany
子句相当复杂(我只是编写了一个更简单的例子),如果它已经存在于列表中,我肯定不想处理3
。
我可以检查原始列表中是否存在3
。但如果我在3
条款中得到SelectMany
,我不想再得到它。例如,如果我有这个清单:
int[] a = {1,2,3,4,5,2};
我会得到这个:
{1,2,3,3,4,5,5,2,3}
因此,最后再次返回v
(我的原始值)和v+1
。这样你就可以更好地理解v+1
代表我想要避免的一些处理。
总结一下,这就是我想要的:
SelectMany
) {v}
已存在,我应该只返回{v+1}
。的(没有线索...) 我想到的一件事是编写一个可能符合我需求的自定义SelectMany
,但我想确定没有内置的方法来执行此操作。
编辑:我相信我可能会因为我的榜样误导你们。我知道如何确定v+1
是否在列表中。要清楚,我有一个对象有2个int属性,Id和IdParent。我需要“回报”所有对象和他们的父母。但我只有ParentId,它来自对象本身。我能够知道列表中是否有v+1
,因为我可以检查其中的任何对象是否与我正在检查的ParentId具有相同的ID。
答案:我最终使用了Aggregate
,这可以用来做我正在寻找的内容。
答案 0 :(得分:3)
这个简单的循环与HashSet<int>
有帮助吗?
int[] a = {1,2,3,4,5,2};
var aLookupList = new HashSet<int>();
foreach (int i in a)
{
bool isEven = i % 2 == 0;
if (isEven)
{
aLookupList.Add(i);
aLookupList.Add(i + 1);
}
else
{
aLookupList.Add(i);
}
}
var result = aLookupList.ToArray();
答案 1 :(得分:1)
使用Aggregate
方法怎么样?您不会处理列表中已有的数字,也不会处理原始列表中的数字或应用的数字(v + 1)
int[] v = { 1, 2, 3, 4, 5, 2 };
var result = v.Aggregate(new List<int>(),
(acc, next) =>
{
if (!acc.Contains(next))
return (next % 2 == 0) ? acc.Concat(new int[] { next, next + 1 }).ToList()
: acc.Concat(new int[] { next }).ToList();
else
return acc;
}).ToArray();
答案 2 :(得分:0)
var existing = new HashSet<int>(a);
var result = existing
.Where(v => v % 2 == 0 && !existing.Contains(v + 1))
.Select(v => v + 1)
.Concat(existing)
.ToArray();
答案 3 :(得分:0)
据我所知,你有这样的意见:
int[] a = {1,2,3,4,5};
输出也应为{1,2,3,4,5}
,因为您不需要如您所述的重复数字。
因为您使用array
作为输入,所以您可以尝试以下代码:
var output = a.SelectMany((x,i)=> x % 2 == 0 ? new []{x,x+1} :
i > 0 && a[i-1]==x-1 ? new int[]{} : new []{x});
//if the input is {1,2,4,5}
//The output is also {1,2,3,4,5}