试图弄清楚如何使用 .Where 将字符串字符添加到字符串数组

Trying to figure out how to add a string character to a string array using .Where

下面是我的字符串数组。我得到了这个 .Where 在线代码,我发现它真的很有趣,我尝试修改它以使其添加一个字符而不是删除一个字符。但是,我在最后一行的“indexremove”变量下不断收到“方法名称预期错误”。 这个问题有什么解决办法吗?还是我的修改不起作用?

string[] TestArray = {"a", "b", "c", "d", "e"};

int indexremove = 0;      // for removing the character in the 1st position; a.

TestArray = TestArray.Where((source, index) => index != indexremove).ToArray(); //source, index points to the array's character collection, and index != indexremove causes A to be removed from the index of the array. Then it is converted to an array.

foreach (string value in TestArray) {Console.WriteLine(value); //displays output of new array without "a" }

string indextoadd = "a"; //trying to re-add the character back in to the array


TestArray = TestArray.Where((source, index) => index + indexremove(indextoadd)).ToArray(); //Method Name Expected on indexremove
using System;
using System.Linq;

namespace Problems
{
    class Program
    {
        static void Main(string[] args)
        {            
                string[] TestArray = { "a", "b", "c", "d", "e" };

                int indexremove = 1;

                 var RemovedIndex = TestArray.Skip(indexremove);

                foreach(var t in RemovedIndex)
            {
                Console.WriteLine(t);
            }

            RemovedIndex.ToList().Insert(indexremove, "a");
            RemovedIndex = TestArray.ToArray();

                foreach (var t in RemovedIndex)
            {
                Console.WriteLine(t);
            }
        }
    }
}

由于数组是固定的,我选择跳过数组中的第一个索引。打印第一个控制台可以看到第一个字符被跳过了。

然后,因为你需要回字符,所以我将当前数组转换为列表并将字符插入回。记得之后将其转换回数组。

通过 运行 第二个循环查看结果。

Where 不是这样的。它是一种过滤设备,因此本质上不能用于 extend/add 事物列表。如果某些测试 returns false

对于任何给定的项目列表;

string[] testArray = {"a", "b", "c", "d", "e"};

您可以编写一个 Where,然后将一小段代码(我们倾向于将其称为 lambda)传递给 Where,就像一个无名方法。它必须接受一个或两个参数,并且必须 return 一个布尔值。 Where 将遍历项目的输入列表,调用您在每个项目上传递的 lambda。如果 lambda return 为真,则输出输入项。如果return为false,则不输出正在循环的列表项

这些是概念上的等价物:

//this nice short thing
testArray.Where(s => s.Length == 1);


//is like this longer thing

public bool LengthIs1(string s){
  return s.Length == 1;
}
...
foreach(var s in testArray)
  if(LengthIs1(s))
    output s;    //this is a pretend thing: `output` doesn't exist but it means I don't also have to explain yield return. Just imagine that it sends the value out and carries on looping

例子

testArray.Where(s => true);        //every item will be output
testArray.Where(s => false);       //no item will be output
testArray.Where(s => s == "a");    //only items equal to "a" will be output 
testArray.Where(s => s.StartsWith("b"));    //only items starting with b will be output 
testArray.Where(s => DateTime.Now.DayOfWeek == DayOfWeek.Tuesday);     //every item will be output if it's Tuesday, otherwise no item will be output

这些是仅将一个参数 s 传递给 lambda 的示例。还有另一种形式,您正在使用的形式,其中 lambda 可以有两个参数 - 第一个参数也是数组中的项目。第二个参数是item在数组中的索引

testArray.Where((s,index) => true);          //every item will be output
testArray.Where((s,index) => index == 0);    //only the first item will be output
testArray.Where((s,index) => index != 1);    //everything apart from the second item will be output
testArray.Where((s,index) => index%2 == 0);  //even indexed items will be output

如您所见,没有任何扩展或添加更多项目的范围。你从 100 个项目开始,你只能输出 0 到 100 个项目之间的某处

在您发布的代码中,第一项被过滤掉,因为 lambda 评估索引与要删除的索引,并且在它们不相同的所有情况下 return 为真(保留),并且 return false(删除)当它们相同时

如果你想输出更多的项目你必须使用别的东西,比如Concat

new[]{1,2}.Concat(new[]{3,4})

这将输出 1,2,3,4 的枚举

因为 Where 产生一个可枚举的东西,而 Concat 可以在一个可枚举的东西上调用并接受另一个可枚举的东西作为参数,这意味着我们可以做这样的事情:

testArray
  .Where((s,index) => index != indextoremove)
  .Concat( 
    testArray.Where((s,index) => index == indextoremove)
  )

第一个 Where 仅排除 indextoremove(保留其余部分),第二个 Where 仅保留 indextoremove(排除其余部分)。 Concat 只会有效地采用第一个序列,其中“a”已被排除,然后连接到第二个序列,其中“a”是唯一包含的序列。这实际上会将“a”从开头移动到序列的结尾

效率低得可怕,但这个例子更多的是学习


(source, index) => index + indexremove(indextoadd)

唉,这是一个语法错误。您已经使 indextoadd 成为一个字符串,而 index to remove 是一个 int。你不能在一个 int 变量名后面加上一个 ( 因为你不能 execute/call 一个 int。你也不能执行一个 int 传递一个字符串给它。作为 lambda 棺材的最后一颗钉子,它应该 return 一个 bool 但你已经做了一些接近数字结果的事情,如果 int + int(string) 甚至是可能的。在完整的方法术语中你已经做了类似的事情:

public bool AMethod(string source, int index){
  string indextoadd = "a";
  int indexremove = 1;
  return index + indexremove(indextoadd);
}

希望你能看到其中有很多语法和逻辑问题..