5

Here is what I am trying to do but with no success. I want to call from x in list1 and join y in list2 where regex.Match(x.Value).Success. After these steps I need to call String.Replace twice on x.Value. Then call the on and select operators. I want it to look something like the second example. How can this be acheived?

Here is how my lists look like:

list1              list2
Name    Value      Name    Value
item.1  $(prod1)   prod1   prodVal1
item.2  $(prod2)   prod2   prodVal2
item.3  prod3      prod3   prodVal3

Here is how my lists should look like:

updatedList         
Name    Value     
item.1  prodVal1   
item.2  prodVal2       
item.3  prod3      

Example 1 (This is what I currently have):

foreach (var x in list1)
{
    Match match = reg.Match(x.Value);
    if (match.Success)
    {
        x.Value = x.Value.Replace("$(", "");
        x.Value = x.Value.Replace(")", "");
    }
}

var commonItems = from x in list1
                  join y in list2
                  on x.Value equals y.Name
                  //where regex.Match(x.Value).Success
                  select new { Item = x, NewValue = y.Value };

foreach (var x in commonItems)
{
    x.Item.Value = x.NewValue;
}

Example 2:

var commonItems = from x in list1
                  join y in list2
                  where regex.Match(x.Value).Success
                  //do x.Value.Replace("$(", "")
                  //do x.Value.Replace(")", "")
                  //then call
                  on x.Value equals y.Name
                  select new { Item = x, NewValue = y.Value };

foreach (var x in commonItems)
{
    x.Item.Value = x.NewValue;
}
7
  • in the select do you want to return the original value or the value after the string.replace? Commented Aug 27, 2014 at 19:57
  • shouldn't you get a single list in the end? the commonItems list. in your example you have 2 lists... Commented Aug 27, 2014 at 20:17
  • can you really have NULL values in list1? it's going to complicate the query Commented Aug 27, 2014 at 20:28
  • @Vland I changed it, to not have a null. Commented Aug 27, 2014 at 20:29
  • why is item.3 getting prod2 as value in the updatedList? Commented Aug 27, 2014 at 20:30

2 Answers 2

8

If I understood correctly what you want is to use let in your query:

var commonItems = from x in list1
                  join y in list2
                  let newX = x.Value.Replace("$(", "").Replace(")", "")
                  where regex.Match(x.Value).Success
                 &&  newX == y.Name
                  select new { Item = newX, NewValue = y.Value };
Sign up to request clarification or add additional context in comments.

2 Comments

where needs to be before the let, and I get this error: Expected contextual keyword 'on'
@BenScotch Check the documentation on let here
4

Are you sure you need Regex.Match? you could obtain the same result without using it, anyway I added both versions...

In the 1° version you can use a simple If statement to check if the value was changed

NewValue = x.Value != x1 ? y.Value: x.Value 

Sample code

given this class

class MyClass
{
    public string Name { get; set; }
    public string Value { get; set; }
}

.

adding items

        var list1 = new List<MyClass>();
        list1.Add(new MyClass { Name = "item.1", Value = "$(prod1)" } );
        list1.Add(new MyClass { Name = "item.2", Value = "$(prod2)" });
        list1.Add(new MyClass { Name = "item.3", Value = "prod3" });

        var list2 = new List<MyClass>();
        list2.Add(new MyClass { Name = "prod1", Value = "prodVal1" });
        list2.Add(new MyClass { Name = "prod2", Value = "prodVal2" });
        list2.Add(new MyClass { Name = "prod3", Value = "prodVal3" });

getting common list

        var q =  from x in list1
                 let x1 = x.Value.Replace("$(", "").Replace(")", "")
                join y in list2 on x1 equals y.Name
                select new { 
                    Item = x.Name, 
                    NewValue = x.Value != x1 ? y.Value: x.Value 
                };


        foreach (var s in q)
        {
            Console.WriteLine(s.Item + " " + s.NewValue);
        }

result

item.1 prodVal1
item.2 prodVal2
item.3 prod3

PS: I don't think you need Regex, but just in case this version will work using it.

var q = from x in list1
        let x1 = x.Value.Replace("$(", "").Replace(")", "")
        join y in list2 on x1 equals y.Name
        select new
        {
            Item = x.Name,
            NewValue = Regex.Match(x.Value, x1).Success ? x.Value : y.Value
        };

5 Comments

regex.match is needed because i only need to do the replacement on the objects that match.
@BenScotch I handled that adding the IF in the select statement. try it, item.3 is not getting its value replaced
@BenScotch added also the Regex version to it, just check the .Success value in the select statement so you know if you need to change the value or not
the reason why i need the regex, so that i can check the which values i need to do the replacements on, otherwise, there are more replacements than there should be. You definitely deserve the accepted answer!
@BenScotch I understand your need Ben, this is why in both version we check if x1 (the replaced string) is equal to x.value. so we know when we should take the new value and when we should stick with the old one. Regex is usually needed for much more complicated pattern search than a simple string equality check. anyway thanks for the vote and good luck :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.