I have some Dart code that need replace all the keyword to full string based on a json list. I now using the most easy method to replaceAll string one by one but it seem not ok to work on a very long json, how do write a function take json and replace based on the key label field?
String replaceString(String str) {
str = str.replaceAll('key_a', 'created');
str = str.replaceAll('key_b', 'replied');
str = str.replaceAll('key_c', 'assigned');
str = str.replaceAll('key_d', 'unassigned');
str = str.replaceAll('key_e', 'terminated');
return str;
}
json get from api
{
"key_a": {
"label": "created",
"type": ""
},
"key_b": {
"label": "replied",
"type": ""
},
"key_c": {
"label": "assigned",
"type": ""
}
..... and many more
}
CodePudding user response:
You can do like this also:-
String replaceString(String str) {
if(str == "key_a"){
return str.replaceAll('key_a', 'created');
}else if(str == "key_a"){
return str.replaceAll('key_b', 'replied');
}else if(str == "key_c"){
return str.replaceAll('key_c', 'assigned');
}else if(str == "key_d"){
return str.replaceAll('key_d', 'unassigned');
}else {
return str.replaceAll('key_e', 'terminated');
}
}
CodePudding user response:
I don't really know much about your application and the problem you want to solve. E.g. there are some missing details about how long these strings are going to be which are given as input to replaceString and how much performance means here.
My attempted solution is therefore somewhat between horrible and not fantastic when it comes to performance. But the code is somewhat easy to understand which also count for something:
import 'dart:convert';
void main() {
String jsonInput = '''{
"key_a": {
"label": "created",
"type": ""
},
"key_b": {
"label": "replied",
"type": ""
},
"key_c": {
"label": "assigned",
"type": ""
}
}
''';
final keyToLabelMapper = KeyToLabelMapper(jsonInput);
print(keyToLabelMapper.replaceString('this is key_a')); // this is created
}
class KeyToLabelMapper {
// Key = keyword | Value = label
final Map<String, String> _keyToLabelMap;
KeyToLabelMapper(String json) : _keyToLabelMap = _parseJsonToMapperMap(json);
static Map<String, String> _parseJsonToMapperMap(String json) => {
for (final entry in (jsonDecode(json) as Map<String, dynamic>).entries)
entry.key: entry.value['label'] as String
};
// Cached the RegExp. No need for recreating that each time
static final RegExp _wordRegExp = RegExp(r'\S ');
String replaceString(String str) => str.replaceAllMapped(
_wordRegExp, (match) => _keyToLabelMap[match[0]!] ?? match[0]!);
}
So the idea is that we creates a Map which we use for checking if we should do a replacement. For cut the input string into words and check each word against the mapping map. If the word are in the map, we replace the word with what are inside the map. If the word are not in the map, we just use the same word as we got as input (so no replacement is happening).
This is happening with _keyToLabelMap[match[0]!] ?? match[0]! which can be a little confusing but we should notice that [] on Map returns null in case a given key is not in the Map. And ?? is a operator which uses the left side of the expression in case the value is not null, and the right side in case the left side is null.
The ! is needed because [] on regular expression match objects also returns null in case the group is not in the match. But we ignore that problem here since we know for a fact that group 0 does have a value when we are here.
