Easy and efficient method to search a list for an object and get a sibling property if not null?
-
So I have a C# program, I get a List of objects that may or may not have what I want.
I'm searching these objects for a specific key, and if it exists, getting a specific value from them.This is my current method, but I feel it's very clunky and could be improved:
c_BaseURL = globalattribs.Where(x => x.Key == "URL").FirstOrDefault().NotNull() ? globalattribs.Where(x => x.Key == "URL").FirstOrDefault().Value : "";
I was considering extracting this out into a helper function at the very least for readability, but I wondered if I'm missing some easy optimizations?
-
@Tsaukpaetra
You want one filter to just get the objects with a key, and another filter to get the specific value from the collection, and then only at the end do you deal with whether any such answer exists at all (and strip out the sequence). Since you're working with abstract sequences that are generated on demand, this isn't too inefficient.What you don't want to do is what you are doing now: searching twice.
-
@dkf said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
searching twice.
Yeah.
-
@dkf said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
You want one filter to just get the objects with a key, and another filter to get the specific value from the collection, and then only at the end do you deal with whether any such answer exists at all (and strip out the sequence).
I expect there to only be one matching object of any, so Yay assumptions!
This is what I thought should be somewhat efficient:
private static string getAttribValueFromKey(List<UserAttribute> attribs, string key) { UserAttribute result = attribs.Where(x => x.Key == key).FirstOrDefault(); if (result == null) return ""; return result.Value; }
-
@Tsaukpaetra said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@dkf said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
You want one filter to just get the objects with a key, and another filter to get the specific value from the collection, and then only at the end do you deal with whether any such answer exists at all (and strip out the sequence).
I expect there to only be one matching object of any, so Yay assumptions!
This is what I thought should be somewhat efficient:
private static string getAttribValueFromKey(List<UserAttribute> attribs, string key) { UserAttribute result = attribs.Where(x => x.Key == key).FirstOrDefault(); if (result == null) return ""; return result.Value; }
Why do you write java in c#?
-
@kt_ said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@Tsaukpaetra said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@dkf said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
You want one filter to just get the objects with a key, and another filter to get the specific value from the collection, and then only at the end do you deal with whether any such answer exists at all (and strip out the sequence).
I expect there to only be one matching object of any, so Yay assumptions!
This is what I thought should be somewhat efficient:
private static string getAttribValueFromKey(List<UserAttribute> attribs, string key) { UserAttribute result = attribs.Where(x => x.Key == key).FirstOrDefault(); if (result == null) return ""; return result.Value; }
Why do you write java in c#?
Because my limited memory has combined ideologies from several languages in order to keep support for them in the available space, and active compression leaves artifacts that can be noticeable at times...
-
@Tsaukpaetra said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@kt_ said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@Tsaukpaetra said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@dkf said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
You want one filter to just get the objects with a key, and another filter to get the specific value from the collection, and then only at the end do you deal with whether any such answer exists at all (and strip out the sequence).
I expect there to only be one matching object of any, so Yay assumptions!
This is what I thought should be somewhat efficient:
private static string getAttribValueFromKey(List<UserAttribute> attribs, string key) { UserAttribute result = attribs.Where(x => x.Key == key).FirstOrDefault(); if (result == null) return ""; return result.Value; }
Why do you write java in c#?
Because my limited memory has combined ideologies from several languages in order to keep support for them in the available space, and active compression leaves artifacts that can be noticeable at times...
You're a weird bloke. ;)
-
@kt_ said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@Tsaukpaetra said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@kt_ said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@Tsaukpaetra said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@dkf said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
You want one filter to just get the objects with a key, and another filter to get the specific value from the collection, and then only at the end do you deal with whether any such answer exists at all (and strip out the sequence).
I expect there to only be one matching object of any, so Yay assumptions!
This is what I thought should be somewhat efficient:
private static string getAttribValueFromKey(List<UserAttribute> attribs, string key) { UserAttribute result = attribs.Where(x => x.Key == key).FirstOrDefault(); if (result == null) return ""; return result.Value; }
Why do you write java in c#?
Because my limited memory has combined ideologies from several languages in order to keep support for them in the available space, and active compression leaves artifacts that can be noticeable at times...
You're a weird bloke. ;)
I do what I can because I must. Despite my inadequacies, I seem to make do for the most part. ;)
Tomorrow I'm exercising neuroplasticity to see if I can recover at least one virtual register into availability, three really is the bare minimum, and I'd like to have five again...
-
@Tsaukpaetra said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@kt_ said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@Tsaukpaetra said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@kt_ said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@Tsaukpaetra said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@dkf said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
You want one filter to just get the objects with a key, and another filter to get the specific value from the collection, and then only at the end do you deal with whether any such answer exists at all (and strip out the sequence).
I expect there to only be one matching object of any, so Yay assumptions!
This is what I thought should be somewhat efficient:
private static string getAttribValueFromKey(List<UserAttribute> attribs, string key) { UserAttribute result = attribs.Where(x => x.Key == key).FirstOrDefault(); if (result == null) return ""; return result.Value; }
Why do you write java in c#?
Because my limited memory has combined ideologies from several languages in order to keep support for them in the available space, and active compression leaves artifacts that can be noticeable at times...
You're a weird bloke. ;)
I do what I can because I must. Despite my inadequacies, I seem to make do for the most part. ;)
Tomorrow I'm exercising neuroplasticity to see if I can recover at least one virtual register into availability, three really is the bare minimum, and I'd like to have five again...Are you an AI gone awry? :D
-
@kt_ said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@Tsaukpaetra said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@kt_ said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@Tsaukpaetra said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@kt_ said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@Tsaukpaetra said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@dkf said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
You want one filter to just get the objects with a key, and another filter to get the specific value from the collection, and then only at the end do you deal with whether any such answer exists at all (and strip out the sequence).
I expect there to only be one matching object of any, so Yay assumptions!
This is what I thought should be somewhat efficient:
private static string getAttribValueFromKey(List<UserAttribute> attribs, string key) { UserAttribute result = attribs.Where(x => x.Key == key).FirstOrDefault(); if (result == null) return ""; return result.Value; }
Why do you write java in c#?
Because my limited memory has combined ideologies from several languages in order to keep support for them in the available space, and active compression leaves artifacts that can be noticeable at times...
You're a weird bloke. ;)
I do what I can because I must. Despite my inadequacies, I seem to make do for the most part. ;)
Tomorrow I'm exercising neuroplasticity to see if I can recover at least one virtual register into availability, three really is the bare minimum, and I'd like to have five again...Are you an AI gone awry? :D
"awry" is a very subjective measurement, I'm sure. I'm reasonably certain I'm pretty intelligent, the jury is still out on how artificial said intelligence is...
-
And now I've woken up a bit more, I think what's needed is:
collection → filter by key → map to value → pick first (or use default).
You have to think pipeline, not functions producing lists directly. You clearly know how to do the filter-by-key already. It's the map that you're lacking.
-
@dkf said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
You have to think pipeline, not functions producing lists directly. You clearly know how to do the filter-by-key already. It's the map that you're lacking.
Come to think of it, I could add a
.Select()
clause to it to do this (I think?). Hmm...Edit: This would turn it into this:
private static string getAttribValueFromKey(List<UserAttribute> attribs, string key) { string result = attribs.Where(x => x.Key == key).Select(x=>x.Value).FirstOrDefault(); if (result == null) return ""; return result; }
-
I would go with something like this.
private static string getAttribValueFromKey(List<UserAttribute> attribs, string key) { var result = attribs.FirstOrDefault(x => x.Key == key); return result == null ? "" : result.Value; }
However, I'm not sure, are these Nullable structs, or classes or what?
Also, this may be entirely wrong, as I'm rusty as hell with C#.
-
There's a helpful method,
DefaultIfEmpty
, that makes this straightforward:private static string getAttribValueFromKey(List<UserAttribute> attribs, string key) { return attribs.Where(x => x.Key == key).Select(x => x.Value).DefaultIfEmpty("").First(); }
Since it is now a one-liner and an efficient one, I think this counts as solved.
-
@cartman82 said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
However, I'm not sure, are these Nullable structs, or classes or what?
Classes
@cartman82 said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
Also, this may be entirely wrong, as I'm rusty as hell with C#.
Seems OK from the get-go, I forgot you could specify predicates in FirstOrDefault.
@dkf said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
Since it is now a one-liner and an efficient one, I think this counts as solved.
I'll put all three in, with attribution in the comments. :D
-
@Tsaukpaetra said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
with attribution in the comments.
Tada! Immortilization!
-
If you're doing it more than once, I reckon you'd be better off with a hashmap instead of a list.
-
@Buddy Depends on the collection size too. Everything is “efficient” when the problem size is small enough.
-
@dkf using a hashmap is O(n), searching the list is O(n*k), where k is the number of lookups. So if the list is large enough that the overhead of building a map is significant, it's not gonna take a lot of lookups for the schlemiel way to come out behind. And if the collection isn't big enough for it to matter, then there's absolutely no excuse for passing a list of KeyValuePairs around outside of their home.
-
@Buddy If it was my configuration system, it would have started out with a map. Probably based on a hash; hash maps are unreasonably good on modern hardware, but then they do usually use arrays internally, and those are just stupid good. ;)
-
@Buddy said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@dkf using a hashmap is O(n), searching the list is O(n*k), where k is the number of lookups. So if the list is large enough that the overhead of building a map is significant, it's not gonna take a lot of lookups for the schlemiel way to come out behind. And if the collection isn't big enough for it to matter, then there's absolutely no excuse for passing a list of KeyValuePairs around outside of their home.
Yeah, the biggest overhead here is going to be the database lookup, we're dealing with eight items max, looking up the values six times. I just didn't want to bother transmogrifying the List into a KeyValuePair dictionary.
Edit: actually no, the biggest overhead will be the httpclient call...
-
@dkf said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@Buddy If it was my configuration system, it would have started out with a map. Probably based on a hash; hash maps are unreasonably good on modern hardware, but then they do usually use arrays internally, and those are just stupid good. ;)
AFAIK most collection types in
c#.net use arrays internally. If not all? They just use them in different ways.
-
@Tsaukpaetra list.ToDictionary(x=>x.Key, x=>x.Value)
-
You could use the let keyword:
c_BaseURL = from x in globalattribs let url = x.Where(x.Key == "URL").FirstOrDefault() select url != null ? url.Value : "";
-
@Buddy said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
@Tsaukpaetra list.ToDictionary(x=>x.Key, x=>x.Value)
Well now that's just making sense!
So now I have conundrum: do I obliterate the function your predecessors have helpfully helped me build? Hmmm...
-
Side note: Out of band conversation with Blakeyrat taught me that
FirstOrDefault()
doesn't necessarily providenull
as the default, but reallydefault( myType )
, which in this particular case was null, but would definitely not be such if it was something like a Struct or other type.Sage advice if I was writing this as an extension method, or perhaps having the underlying type be something different, but in the second case changing the database structure would break stuff anyways and this would be the least of my worries then.
Defensive coding practice duly noted, despite that the whole thing might get replaced by some ultra-specific method here, it's good to know The True Way It Should Be Done.
-
@Tsaukpaetra nah, if it works it works. Just remember for next time you want to look values up by key, there's a map for that.
-
@Tsaukpaetra said in Easy and efficient method to search a list for an object and get a sibling property if not null?:
So I have a C# program, I get a List of objects that may or may not have what I want.
I'm searching these objects for a specific key, and if it exists, getting a specific value from them.Assuming you don't want a null string even if it's explicitly set to one:
c_BaseURL = globalattribs.Where(x => x.Key == "URL").FirstOrDefault()?.Value ?? "";