在字符串数组引用的字符串上设置字符串

时间:2015-12-18 06:01:58

标签: c# string

string db;
ComboBox fieldBox = new ComboBox()
TextBox ValueBox = new TextBox()
ListBox dbValues = new ListBox()

private void LoadDB()
{
    //Structure
    string myStruct = "NAME\nAGE\nSEX\nSKILL
    db = "John\t20\tMale\tNoob\n
                   Joe\t20\tMale\tMedium\n
                   Jessica\t27\tFemale\tExpert\n
                   John\t21\tMale\tMedium
                  ";

    //Load struct to combobox
    string[] mbstr = myStruct.Split('\n');
    for (int i = 0; i < mbstr.Length; i++)
    {
        fieldBox.Items.Add(mbstr[i]);
    }

    string[] db2 = db.Split('\n');
    for (int i = 1; i < db2.Length - 1; i++)
    {
        //Display name and age in combobox
        dbValues.Items.Add(db2[i].Split('\t')[0] + " - " +   db2[i].Split('\t')[1]);
    }
}

void ValueBoxKeyDown(object sender, KeyEventArgs e)
{
    if(e.KeyCode != Keys.Enter)
        return;

    db.Split('\n')[dbValues.SelectedIndex].Split('\t')[fieldBox.SelectedIndex] = valueBox.Text;

    MessageBox.Show("Value set: " +
                           db.Split('\n')[dbValues.SelectedIndex + 1].Split('\t')[fieldBox.SelectedIndex]
                            + " to " + valueBox.Text + ".");
}

这是它失败的地方:

db.Split('\n')[dbValues.SelectedIndex].Split('\t')[fieldBox.SelectedIndex] = valueBox.Text;

我尝试了这个,并尝试分配给db,但不能正常工作。我的原始字符串没有变化。

我不想转换为列表和字符串,我想直接更改。 我怎么能这样做?

2 个答案:

答案 0 :(得分:1)

由于字符串是不可变的,因此无法更改返回字符串的方法的返回值。您可以做的是以下内容:

string myDatabase = 
    "Garry\t19\tMale\tNoob\n" +
    "Joe\t25\tMale\tMedium\n" +
    "Gary\t33\tFemale\tExpert";

var tmp = "";
foreach(var line in myString.Split('\n')) {
    tmp = tmp + Regex.Replace(line, "^.*?(?=\\t)", myReplaceText);
}
myString = tmp;

此正则表达式将搜索每行中第一个选项卡之前的所有内容,将其替换为"Jerry"并将每个如此替换的行连接到myString

答案 1 :(得分:1)

你的第一个问题是你的字符串:除非你使用@escaping,你不能让你的字符串跨越多行,如果你使用@escaping你不能做\ t或\ n并保留它们的标签的转义含义换行符。

第二个问题是对.NET字符串的基本误解,字符串是不可变的。 Split会创建一个数组,没有引用回原始字符串,或者第二个数组是你的分裂。您需要执行以下操作:

[TestClass]
public class StringTest
{
    public TestContext TestContext { get; set; }
    [TestMethod]
    public void RewriteString()
    {
        var str = "Garry\t19\tMale\tNoob\n" +
            "Joe\t25\tMale\tMedium\n" +
            "Gary\t33\tFemale\tExpert";

        var rows = str.Split('\n');
        var columns = rows[0].Split('\t');
        columns[0] = "Jerry";
        rows[0] = string.Join("\t", columns);
        str = string.Join("\n", rows);
        TestContext.WriteLine(str);
    }
}
 Test Name: RewriteString
 Test Outcome:  Passed
 Result StandardOutput: TestContext Messages:
 Jerry  19  Male    Noob
 Joe    25  Male    Medium
 Gary   33  Female  Expert

真的希望有一种更简单的方法来实现这一点,可能使用正则表达式吗?

现在要真正看看你的(新)问题。我已经完全重构了你的内容,因为我不知道你的数据情况我不完全确定使用字符串作为数据库是一个好主意:(由于使用了动态,这将编译而没有任何引用)。

public class SomeView
{
    string db;
    dynamic fieldBox = null;
    dynamic valueBox = null;
    dynamic dbValues = null;
    dynamic MessageBox = null;
    private void LoadDB()
    {
        //Structure
        string myStruct = "NAME\nAGE\nSEX\nSKILL";
        db = "John\t20\tMale\tNoob\n" +
                       "Joe\t20\tMale\tMedium\n" +
                       "Jessica\t27\tFemale\tExpert\n" +
                       "John\t21\tMale\tMedium";

        //Load struct to combobox
        string[] mbstr = myStruct.Split('\n');
        for (int i = 0; i < mbstr.Length; i++)
        {
            fieldBox.Items.Add(mbstr[i]);
        }

        string[] db2 = db .Split('\n');
        for (int i = 1; i < db2.Length - 1; i++)
        {
            var data = db2[i].Split('\t'); //expensive only do once
            //Display name and age in combobox
            dbValues.Items.Add(data[0] + " - " + data[1]);
        }
    }
    protected string Transform(string value, int row, int column, string replacement, out string old)
    {
        var rows = value.Split('\n');
        var columns = rows[row].Split('\t');
        old = columns[column];
        columns[column] = replacement;
        rows[row] = string.Join("\t", columns);
        return string.Join("\n", rows);
    }
    void ValueBoxKeyDown(object sender, dynamic e)
    {
        if (e.KeyCode != "enter")
            return;
        string old;
        string newValue = this.Transform(db, dbValues.SelectedIndex, fieldBox.SelectedIndex, valueBox.Text, out old);

        MessageBox.Show("Value set: " + old + " to " + valueBox.Text + ".");
    }
}

所以这更好:

public class SomeView
{
    dynamic fieldBox = null;
    dynamic valueBox = null;
    dynamic dbValues = null;
    dynamic MessageBox = null;
    private List<Person> People = new List<Person>();
    private void LoadDB()
    {
        //Structure
        string myStruct = "NAME\nAGE\nSEX\nSKILL";
        string db = "John\t20\tMale\tNoob\n" +
                       "Joe\t20\tMale\tMedium\n" +
                       "Jessica\t27\tFemale\tExpert\n" +
                       "John\t21\tMale\tMedium";
        //Load struct to combobox
        string[] mbstr = myStruct.Split('\n');
        for (int i = 0; i < mbstr.Length; i++)
        {
            fieldBox.Items.Add(mbstr[i]);
        }
        People.Clear();
        foreach(var row in db.Split('\n'))
        {
            var columns = row.Split('\t');
            Person p = new Person();
            p.Name = columns[0];
            p.Age = int.Parse(columns[1]);
            p.Sex = (Person.Sexs)Enum.Parse(typeof(Person.Sexs), columns[2]);
            p.SkillLevel = (Person.SkillLevels)Enum.Parse(typeof(Person.SkillLevels), columns[2]);
            People.Add(p);
            dbValues.Items.Add(string.Format("{0}-{1}", p.Name, p.Age);
        }
    }
    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public enum Sexs
        {
            Male,
            Female
        }
        public Sexs Sex { get; set; }
        public enum SkillLevels
        {
            Noob,
            Medium,
            Expert
        }
        public SkillLevels SkillLevel { get; set; }
    }
    void ValueBoxKeyDown(object sender, dynamic e)
    {
        if (e.KeyCode != "enter")
            return;
        Person p = this.People[dbValues.SelectedIndex];
        switch((int)fieldBox.SelectedIndex)
        {
            case 0: p.Name = valueBox.Text; break;
            case 1: p.Age = int.Parse(valueBox.Text); break;
            case 2: p.Sex = (Person.Sexs)Enum.Parse(typeof(Person.Sexs), valueBox.Text); break;
            case 3: p.SkillLevel = (Person.SkillLevels)Enum.Parse(typeof(Person.SkillLevels), valueBox.Text); break;
            default: throw new NotImplementedException();
        }
        MessageBox.Show("Value set: " + old + " to " + valueBox.Text + ".");
    }
}

然而,这仍然是垃圾,因为如果你有一个强类型数据集,你实际上可以将它绑定到表单控件而不直接操作该项。 https://msdn.microsoft.com/en-us/library/c8aebh9k(v=vs.110).aspx