How to add any symbols after prefix_? - dictionary

is there any solution? e.g. I have data in Map with key favorites_ prefix and values _suffix (for example: favorites_jeans, favorites_suit,...,). I want to by dint of loop get that values and set in List, because of it I must give keys of map, right?
I want to know how can I get values of myMap["favorites_*"] (* - after the favorites_ any symbols).

List<String> favoritesStrings = ['favorite_name','favorite_jeans',];
Map<String,dynamic> myMap = {
favoritesStrings[0]:'0',
favoritesStrings[1]:'1',
'someKey':'2',
'anotherKey':'3',
};
favoritesStrings.forEach((favorite)=>print(myMap[favorite]));//prints 0 1

As per what I understood, you want to fetch value from map using "favorites_" + a dynamic value from list as key.
You just have to use String templates and use $ to insert suffix variable to build key dynamically:
List<String> suffixList = ["jeans", "suit", "shirt"];
for(String suffix in suffixList) {
var item = myMap["favorites_$suffix"];
// Do something with item
}
Hope it helps

Related

Kotlin Map<String, List<Object>> values are changed after toSortedMap call

I got such a map
Map<String, List<Object>>
when I use
map.toSortedMap(comparator)
and comparing values by keys I got sorted map but amount of objects in each value list is also changed (reduced). It's super strange. Under the hood toSortedMap method creates TreeMap with the given comparator, I don't know TreeMap internals but I assume that any map should not change values but only manipulate with the keys. Is this something that is ok for TreeMap or is it a bug in Kotlin library?
Edit
Code I get this issue on:
val categoriesKeys = listOf("key1", "key2", etc)
val categoriesKeysOrdersMap = mapOf("key1" to 0, "key2" to 1, etc)
val model = listOf(MyModel(..), MyModel(..), etc)
val categoryKeyToModelsMap = categoriesKeys
.asSequence()
.map { key ->
key to model.filter {
it.categories?.contains(key) == true
}
}
.filter { it.second.isNotEmpty() }
.toMap()
.toSortedMap(compareBy { categoriesKeysOrdersMap[it] })
On toMap step I have the map I want but not sorted, but after toSortedMap my data is messed up. Comparator compares by int value from categoriesKeysOrdersMap using key from category.

kotlin adding pair to map when value is a list

I know this is basic but can I do this in a shorter way:
val ss = mutableMapOf<String, MutableList<String>>()
if(ss["new_key"] != null){
ss["new_key"]!!.add("NEW")
}
else{
ss["new_key"] = mutableListOf("OLD")
}
This basically checks if the key exists in the map
if it does an element is appended to the list(value) otherwise a new key-value pair is created
Can't I create a new key on the go? like this:
ss["new_key"].add("OLD")
ss["new_key"].add("NEW")
You have at least 2 options:
use computeIfAbsent:
ss.computeIfAbsent("new_key") { mutableListOf() } += "NEW"
use getOrPut:
ss.getOrPut("new_key", ::mutableListOf) += "NEW"

Java 8 Streams API to filter Map entries

I have a the following container in Java that I need to work on
Map<String, List<Entry<Parameter, String>>>
Where Parameter is an enumerated type defined as follows:
public enum Parameter {
Param1,
Param2,
Param3
}
The code below shows how I initialize the map structure - effectively putting 2 rows in the container.
Map<String, List<Entry<Parameter, String>>> map2 = new HashMap<String, List<Entry<Parameter, String>>>() {{
put("SERVICE1", new ArrayList<Entry<Parameter, String>>(){{
add (new AbstractMap.SimpleEntry<>(Parameter.Param1,"val1"));
add (new AbstractMap.SimpleEntry<>(Parameter.Param2,"val2"));
add (new AbstractMap.SimpleEntry<>(Parameter.Param3,"val3"));
}});
put("SERVICE2", new ArrayList<Entry<Parameter, String>>(){{
add (new AbstractMap.SimpleEntry<>(Parameter.Param1,"val4"));
add (new AbstractMap.SimpleEntry<>(Parameter.Param2,"val5"));
add (new AbstractMap.SimpleEntry<>(Parameter.Param3,"val6"));
}});
}};
I need to use the java 8 streams api to find the val1 and val2 values from "SERVICE1" but I do not know the correct java streams filter and mapping syntax.
The nearest thing I can come up with is the following, but this only filters at the top level and it returns a list of lists rather than the list of Parameter.Param1,"val1" & Parameter.Param2,"val3" that I am looking for from the SERVICE1 row.
List<List<Entry<Parameter, String>>> listOfLists = myMap.entrySet().stream()
.filter(next -> next.getKey().equals("SERVICE1"))
.map(Map.Entry::getValue)
.collect(Collectors.toList());
listOfLists.size();
If you only need the "val1" and "val2" values, you can first use getOrDefault to get the corresponding list, and then filter on the entries' keys to get entries with Param1 or Param2 as key, and finally apply map again to get the values of these entries.
List<String> list =
myMap.getOrDefault("SERVICE1", Collections.emptyList())
.stream()
.filter(e -> e.getKey() == Parameter.Param1 || e.getKey() == Parameter.Param2)
.map(Map.Entry::getValue)
.collect(Collectors.toList());
Also you might be interested to look at Efficiency of Java "Double Brace Initialization"?

$.grep on JSON data in multiple array.fields using wildcards?

First off I have looked through similar looking questions but have not found the exact problem asked or answered, so here goes :
I have a JSON Object which consists of about 900+ posts. Looking like this:
var JsonData = [{"rowNumber":563663,"hasWarning":true,"isInvoiceAccount":true,"phone":"","name":"Romerike AS","address1":"Co/Skanning","address2":"PB 52","attention":"","mobile":"","email":"fakt#bos.no","fax":"","zipCity":"N-1471 Askim","invoiceAccount":"","notes":null,"account":"3","country":"NORGE","salesRep":"4","countryCode":"no"},{"rowNumber":563674,"hasWarning":false,"isInvoiceAccount":true,"phone":"","name":"LILLEHAMMER","address1":"POSTBOKS 110","address2":"","attention":"","mobile":"","email":"","fax":"","zipCity":"N-2605 LILLEHAMMER","invoiceAccount":"","notes":null,"account":"14","country":"NORGE","salesRep":"4","countryCode":"no"},{"rowNumber":563676,"hasWarning":true,"isInvoiceAccount":true,"phone":"63929788","name":"Askim Bil AS","address1":"Postboks 82","address2":"","attention":"","mobile":"","email":"karosseri#nyg.no","fax":"","zipCity":"N-2051 Askim","invoiceAccount":"","notes":null,"account":"16","country":"NORGE","salesRep":"4","countryCode":"no"},{"rowNumber":563686,"hasWarning":false,"isInvoiceAccount":true,"phone":"69826060","name":"KAROSSERI A/S","address1":"POSTBOKS 165","address2":"","attention":"","mobile":"","email":"tkar#online.no","fax":"","zipCity":"N-1860 TRØGSTAD","invoiceAccount":"","notes":null,"account":"26","country":"NORGE","salesRep":"4","countryCode":"no"},{"rowNumber":563690,"hasWarning":false,"isInvoiceAccount":true,"phone":"","name":"AUTOSERVICE A/S","address1":"POSTBOKS 15","address2":"","attention":"","mobile":"","email":"","fax":"","zipCity":"N-2851 LENA","invoiceAccount":"","notes":null,"account":"30","country":"NORGE","salesRep":"4","countryCode":"no"},{"rowNumber":563691,"hasWarning":false,"isInvoiceAccount":false,"phone":"","name":"ØYHUS A/S","address1":"POSTBOKS 321","address2":"","attention":"John Doe","mobile":"","email":"","fax":"","zipCity":"N-2817 GJØVIK","invoiceAccount":"","notes":null,"account":"31","country":"NORGE","salesRep":"4","countryCode":"no"}];
I want to filter these data before I read them into a table using $.grep.
The JSON data have been loaded as an object.
In the HTML page I have a textfield named "filter".
The following code works, but only when I search for an exact match:
var JsonFiltered = $.grep(JsonData, function (element, index) {
return element.zipCity == $('#filter').val();
});
$.each( JsonFiltered, function ( index, value ) {
// sorting through the array adding values to a table
[...]
});
Problem 1:
I want to use Wildcards when filtering.
I read something about using regexp but I haven't found any viable examples.
Problem 2:
I want to be able to filter more than one column.
Example: filtering the word "Askim" in both element.name and element.zipCity
So I figured out the solutions myself...
Using Wildcards:
var search_term = $('#filter').val();
var search = new RegExp(search_term, "i");
var JsonFiltered = $.grep(JsonTest, function (element, index) {
var zipC = search.test(element.zipCity)
var names = search.test(element.name)
return zipC + names ;
The solution was to use "new RegExp" with the filter "i" setting.
then I took two search.tests combined them in the return command and... presto
Hope this helps anyone else.

How use a variable name to point different data types with the same name?

I have 2 List one stores the name of filterable columns(of type DropDown) and another store the values to load in those filterable columns.
List<string> filterableFields = new List<string>() { "A_B", "C_D", "E_F" };
List<string> AB, CD , EF;
Now at the run time I get the data from web service and I have written a function to to extract values for these filterable fields and store the values to 2nd List.
private void prepareListForFilterableColumns(XDocument records)
{
foreach (var currentField in filterableFields)
{
var values = (from xml in records.Descendants(z + "row")
let val = (string)xml.Attribute("ows_" + currentField.Replace("_", "_x0020_"))
where val != ""
orderby val
select val
).Distinct();
switch (currentField)
{
case "A_B": AB = values.ToList(); break;
case "C_D": CD = values.ToList(); break;
}
}
}
Now I was thinking that instead of hard coding the assignment in swtich case block, If I could just use the first List name "A_B" and replace "_" from it to point to my 2nd List and assign values.ToList() to it.
I understand that c# is a static language, So not sure if we can achieve this, but IF I can it will make my function generic.
Thanks a lot in advance for time and help.
Vishal
You could use a dictionary of lists of strings instead of 3 lists to store the values.
Dictionary<string, List<string>> val lists = new Dictionary<string,List<string>>();
And make the keys of the dictionary equal to the filterables: "AB", "CD",..
then, instead of AB you would use valLists["AB"] and could then reference reach list based on a string key.
The other option would be to use reflection but that would be slower and unnecessarily a bit more complicated.

Resources