Search code examples
c#dynamic-values

find value in List of object by string


I need to find the longest value from a list of objects like this...

var longestValue = list.Max(x => x.Name);

The problem is that I can not access it directly like this but this need to be made in a loop. Here is what I have so far..

        public static void SetPropertyValue(this object obj, string propName, object value)
    {
        obj.GetType().GetProperty(propName).SetValue(obj, value, null);
    }


        var user = new User();

        var list = new List<User>
        {
            new Svedea {Name = "Steve", Car = "Volkswagen"},
            new Svedea {Name = "Denice Longhorn", Car = "Tesla"},
            new Svedea {Name = "Rebecca", Car = "Ford"},
            new Svedea {Name = "Mike O", Car = "Mercedes-Benz"}
        };

        var properties = user.GetType().GetProperties();
        var propList = properties.Select(pi => pi.Name).ToList();

        var newUser = new User();

        foreach (var row in propList)
        {
            // Here I need to find the longest value from the list above like this...
            // var longestValue = list.Max(x => x.row); // This is obviously not correct but I need to find this value needs to be found dynamically

            var longestValue = list.Max(x => x.row);
            newUser.SetPropertyValue(row, longestValue);

        }

Solution

  • Use LINQ OrderByDescending to sort your list by the longest value of Name and the longest value of Car. Then you can create a new User longestUser that has the longest values of Name and Car:

    var longestName = list.OrderByDescending(x => x.Name.Length).First().Name;
    var longestCar = list.OrderByDescending(x => x.Car.Length).First().Car;
    var longestUser = new User() { Name = longestName, Car = longestCar };
    

    longestUser:

    Name = "Denice Longhorn"

    Car = "Mercedes-Benz"

    EDIT:

    I have modified my solution above so that you can access the property names with string values :

    var longestNameUser = list.OrderByDescending(x => x.GetType().GetProperty("Name").GetValue(x, null).ToString().Length).First();
    var longestName = longestNameUser.GetType().GetProperty("Name").GetValue(longestNameUser, null);
    
    var longestCarUser = list.OrderByDescending(x => x.GetType().GetProperty("Car").GetValue(x, null).ToString().Length).First();
    var longestCar = longestCarUser.GetType().GetProperty("Car").GetValue(longestCarUser, null);
    
    var newUser = new User();
    PropertyInfo propertyInfo;
    
    propertyInfo = newUser.GetType().GetProperty("Name");
    propertyInfo.SetValue(newUser, Convert.ChangeType(longestName, propertyInfo.PropertyType), null);
    
    propertyInfo = newUser.GetType().GetProperty("Car");
    propertyInfo.SetValue(newUser, Convert.ChangeType(longestCar, propertyInfo.PropertyType), null);
    

    Your modified for loop :

    var newUser = new User();
    PropertyInfo propertyInfo;
    
    foreach (var row in propList)
    {
        var longestValueUser = list.OrderByDescending(x => x.GetType().GetProperty(row).GetValue(x, null).ToString().Length).First();
        var longestValue = longestValueUser.GetType().GetProperty(row).GetValue(longestValueUser, null);
        propertyInfo = newUser.GetType().GetProperty(row);
        propertyInfo.SetValue(newUser, Convert.ChangeType(longestValue, propertyInfo.PropertyType), null);
    }