Filtering Out Values from a C# Generic Dictionary

Filtering out values from a C# Generic Dictionary

Since Dictionary implements IEnumerable<KeyValuePair<Key, Value>>, you can just use Where:

var matches = dictionary.Where(kvp => !kvp.Value.BooleanProperty);

To recreate a new dictionary if you need it, use the ToDictionary method.

Filter generic list with generic dictionary

As you iterate through 2 data sources I think you cannot join it into 1 LINQ.
The best you can do is to join the first condition to the .Where clause

private List<Dictionary<String, Object>> ValidateScenarioProductItemData(List<Dictionary<String, Object>> pList)
{
var tPeriods = new List<dynamic>();
var tCycleProductItemSales = new List<dynamic>();
foreach (var tItem in pList.Where(x=>!string.IsNullOrEmpty(x["IsInternal"].ToString())))
{
var i = 0;
foreach (var item in tPeriods)
{
i++;
var tHasSails = tCycleProductItemSales.Where(CPIS => CPIS.CycleId == Convert.ToInt32(tItem["CycleId"].ToString()) && CPIS.ProductItemId == Convert.ToInt32(tItem["ProductItemId"].ToString()) && CPIS.PeriodId == Convert.ToInt32(item.Id.ToString()));
if (!tHasSails.Any())
{
tItem[string.Format("Datasource{0}Id", i)] = 0;
}
}
}
return pList;
}

Filtering a Key Value from a Dictionary in C#

A better modeling of the data will be to create a class of the group which will have a name and a collection of animals in it. Then you can hold a collection of groups and query it.

If you want to stick with the dictionary then: As your question is to retrieve the key for a given value out of the list of values for that key, I'd organize the data the other way around:

var map = new Dictionary<string,string>
{
["Cheetah"] = "Cat",
["Lion"] = "Cat",
//....
};

Then you can search by your real key - which is the species and not the group:

if(map.TryGetValue("Lion", out var group)) { }

As it is easier to construct the data by grouping to list of species you can:

var rawData = new List<(string group, List<string> species)>
{
("Cat", new List<string> { "Cheetah", "Lion" }),
//...
};

var result = rawData.SelectMany(item => item.species.Select(s => (s, item.group)))
.ToDictionary(k => k.s, v => v.group);

This works with C#7.0 named tuples. If you are using a previous version you can use anonymous types or "old fashion" tuples

For a pre C# 7.0 initialization of the collection:

var rawData = new List<Tuple<string, List<string>>>
{
Tuple.Create<string,List<string>> ("Cat", new List<string> { "Cheetah", "Lion" })
};

filter items from list of dictionary in c# based on matching key and values

This will give you a list of dictionaries where their address contains "aa"

list.Where(x => x["address"].Contains("aa"));

To ignore case-sensitivity

list.Where(x => x["address"].ToLower().Contains("aa"));

And this will give you a flatten list of records including just pair of key,value where key is "address" and value contains "aa"

list.Where(x => x["address"].Contains("aa")).SelectMany(y=>y.Where(item=>item.Key=="address"));

Finding values in a string:string dictionary where a given filter string is a subset of the key string

I wouldn't use the *'s as a way of differentiating multiple values for the same key, and I'd keep filterPlanet and filterLocation separate. That way you can use a simple O(1) dictionary lookup, rather than iterating across all keys, doing substring searching, etc.

public class PlanetFilterer
{
private readonly Dictionary<string, List<string>> lookup = new Dictionary<string, List<string>>();

public PlanetFilterer(IEnumerable<(string filter, string value)> filters)
{
foreach (var (filter, value) in filters)
{
var filterWithoutStars = filter.TrimEnd('*');
if (!lookup.TryGetValue(filterWithoutStars, out var values))
{
values = new List<string>();
lookup[filterWithoutStars] = values;
}
values.Add(value);
}
}

public IReadOnlyList<string> Lookup(string planet, string location)
{
List<string> results;
if (lookup.TryGetValue(planet + location, out results))
{
return results;
}
if (lookup.TryGetValue(planet, out results))
{
return results;
}
return Array.Empty<string>();
}
}

Usage:

var filters = new[]
{
("examplePlanet", "defaultText0"),
("examplePlanet*", "defaultText1"),
("examplePlanet**", "defaultText2"),
("examplePlanetSpecificlocationA", "specificAText0"),
("examplePlanetSpecificlocationA*", "specificAText1"),
("examplePlanetSpecificlocationB", "specificBText"),
};
var filterer = new PlanetFilterer(filters);

Console.WriteLine(string.Join(", ", filterer.Lookup("examplePlanet", "SpecificlocationA")));
Console.WriteLine(string.Join(", ", filterer.Lookup("examplePlanet", "SpecificlocationB")));
Console.WriteLine(string.Join(", ", filterer.Lookup("examplePlanet", "SpecificlocationC")));

Try it online

Fastest way to filter a dictionary and "simplify" its values in C#

Your problem is your filtering of the SortedDictionary doesn't take advantage of the fact that it is sorted. Since ICollection (and C# generic collections in general) don't implement any sort of efficient splice operation, lookup is your best bet.

Turning your filter around, you get:

var q = Enumerable.Range(0, (Int32)(upperBound - lowerBound).TotalDays+1).Select(n => new { Key = lowerBound.AddDays(n), Item = myInput[lowerBound.AddDays(n)].item1 });

var myOutput = new SortedDictionary<DateTime, double>();

foreach (var pair in q)
myOutput.Add(pair.Key, pair.Item);

The other methods all average about the same time. Using a very small separation in lowerBound and upperBound results in thousands of times faster performance. Even using a two year span results in hundreds of times faster performance when myInput contains 2 million entries.

Note that the scope of speedup really depends on how many entries are in the SortedList, a small list will not show much difference in performance.

Filter a List using Dictionary keys

A generic way to do this would be to the property GetMethod using reflection and caching these to improve performance as reflection can be quite slow. You can also use generics so that it will work with any type. Something like the following may be what you are looking for.

private static List<T> FilterList<T>( IEnumerable<T> source, Dictionary<string, object> propertyFilters )
{
var properties = propertyFilters.Keys.Distinct()
.ToDictionary( x => x, x => typeof ( T ).GetProperty( x ).GetGetMethod() );

IEnumerable<T> result = source.ToList();
foreach ( var propertyFilter in propertyFilters )
{
if ( properties.ContainsKey( propertyFilter.Key ) )
{
result = result.Where( x =>
{
var invoke = properties[propertyFilter.Key].Invoke( x, new object[0] );
if ( propertyFilter.Value is IList )
{
return ( (IList)propertyFilter.Value ).Cast<object>().Any( f =>
{
return f.Equals( invoke );
} );
}
return invoke.Equals( propertyFilter.Value );
} );
}
}
return result.ToList();
}

How to filter dictionary and get the keys from the database table

Not sure what you want to do and the best way to do it. Your question is not very detailed. If you want to compare your files to the list of accountNumbers, this might be a solution:

private void Generate(Document targetDocument, Dictionary<FinancialDocument, PdfDocument> files)
{

foreach(var file in files)
{
if(accountList.Contains(file.Key.MetaData.AccountNumber))
{
// your logic here
var pdfDocument = file.Value;
}
}

}

Filter Dictionary When Items Don't Exist In Another Dictionary

So you want all key-value pairs where all children's int-property either don't exist as key in the other dictionary or that corresponding value is false?

var result = parentDictionary
.Where(kv => kv.Value
.All(c => !selectedChildIds.ContainsKey(c.SomeProperty)
|| !selectedChildIds[c.SomeProperty]));


Related Topics



Leave a reply



Submit