Context
In Dart, if I have a list:
final myList = ['b', 'a'];
and I wanted to sort it alphabetically, I would use:
myList.sort(
(String a, String b) => a.compareTo(b),
);
The output of myList is now:
['a', 'b']
Now, this works on letters that are in the English alphabet.
Question
But if I have a list that's in Hebrew:
final unorderedHebAlphabet = ['א', 'ב'];
I can't sort it as above using with:
unorderedHebAlphabet.sort((String a, String b) =>
a.compareTo(b))
It doesn't sort.
Expected output, instead of:
['א', 'ב']
Should be:
['ב', 'א']
How can I sort a list Alphabetically in the Hebrew language?
Notes
As a reference, the Hebrew alphabet sorted would be in this order:
final sortedHebrewAlphabet = [
'א',
'ב',
'ג',
'ד',
'ה',
'ו',
'ז',
'ח',
'ט',
'י',
'כ',
'ל',
'מ',
'נ',
'ס',
'ע',
'פ',
'צ',
'ק',
'ר',
'ש',
'ת',
];
It does sort (by UTF-16 code units), but it's being shown in an unintuitive way. final unorderedHebAlphabet = ['א', 'ב']; seems to be parsed RTL, so in the constructed list, element 0 is א and element 1 is ב. That's already the desired order, so sorting it does not change it. (Mixing LTR and RTL text is confusing.)
For example:
import 'package:collection/collection.dart';
void main() {
var literal = ['א', 'ב'];
print(literal[0]); // Prints: א
print(literal[1]); // Prints: ב
const alef = 'א';
const bet = 'ב';
const expectedOrder = [alef, bet];
const listEquals = ListEquality();
print(listEquals.equals(literal..sort(), expectedOrder)); // Prints: true
print(listEquals.equals([bet, alef]..sort(), expectedOrder)); // Prints: true
}
You also can observe that the elements are printed in the correct order if you prefix output with the Unicode LTR override (U+202D) to force rendering the text as LTR. Compare:
const ltr = '\u202D';
print('$expectedOrder');
print('$ltr$expectedOrder');
Or you could simply print the elements separately:
expectedOrder.forEach(print);
which prints:
א
ב
I'm not experienced with dealing with RTL text, but I'd probably avoid mixing LTR and RTL text in code and instead express them as hexadecimal Unicode code points to avoid confusion.
It is being printed out in correct order. It's the Console which is printing it in the way it is.
When you save the sorted list into a file and read it again, you get the אב characters as first two characters. So they are being written/iterated in right order.
If you print the values one letter per line, you would get desired result. I am not 100% sure how console is handling it, but dart is simply passing it to the STDOUT (default console), and console is detecting that the string is actually RTL and printing (or writing to STDOUT) in that way.
I did little fiddling which you can see:
import 'dart:io';
void main(List<String> arguments) {
final myList = [
'א',
'ב',
'ג',
'ד',
'ה',
'ו',
'ז',
'ח',
'ט',
'י',
'כ',
'ל',
'מ',
'נ',
'ס',
'ע',
'פ',
'צ',
'ק',
'ר',
'ש',
'ת'
];
// for (var i in myList) {
// print("$i => ${i.runes.toList()}");
// }
myList.sort();
String s = "";
for (var i in myList) {
s += i;
}
print('$s');
print(myList.first);
final file = new File('/Users/rahul/Desktop/string_l/test.txt');
file.writeAsStringSync(s, flush: true);
final read = file.readAsStringSync().substring(0, 2);
print(read);
// You can also verify by calling print with every element
for (var i in myList) {
print(i);
}
}
output
אבגדהוזחטיכלמנסעפצקרשת
א
אב
א
ב
ג
ד
ה
ו
ז
ח
ט
י
כ
ל
מ
נ
ס
ע
פ
צ
ק
ר
ש
ת
import 'dart:io';
final unorderedHebAlphabet = [
'ב',
'ג',
'ד',
'ה',
'ו',
'ז',
'ח',
'ט',
'י',
'כ',
'ל',
'מ',
'נ',
'ס',
'ע',
'פ',
'צ',
'ק',
'ר',
'ש',
'ת',
'א'
];
void main() {
print(unorderedHebAlphabet);
unorderedHebAlphabet
.sort((a, b) => a.codeUnitAt(0).compareTo(b.codeUnitAt(0)));
print(unorderedHebAlphabet);
}
for example if I have a string = "I Like To Play Football" and a list = [Car,Ball,Door,Sky] it should give true.
Use any of list
var list = ["Car","Ball","Door","Sky"];
String text = "i like to play football";
if (list.any((item) => text.toLowerCase().contains(item))) {
//Text has a value from list
}
Here You Go:
void main() {
final String tempString = "I Like To Play Football";
final List<String> tempList = ["Car","Ball","Door","Sky"];
for(var i=0; i < tempList.length; i ++) {
if(tempString.contains(tempList.elementAt(i).toLowerCase())){
print("Found and its ${tempList[i]}");
}
}
}
Regex is your friend here. You can make a simple regex that uses each string in the array as an option (and make it case insensitive) then run the match. I've made an example here in javascript, but it's easy to do in dart
https://api.dart.dev/stable/2.16.1/dart-core/RegExp-class.html
const source = "I Like To Play Football";
const toMatch = ["Car","Ball","Door","Sky"];
let regexString = '';
for (const option of toMatch) {
//adding | modifier after string. Last one is redundant of course
//also I'm not checking for special regex characters in toMatch, but that might be necessary.
regexString += option + '|';
}
// using slice to remove last |
console.log(regexString.slice(0, -1));
const regexp = new RegExp(regexString.slice(0, -1), 'i');
console.log(source.match(regexp));
Here's a short version:
var src = 'I Like To Play Football'.split(' ');
var list = ['Car','Ball','Door','Sky'];
var result = list.any((x) => src.any((y) => y.toLowerCase().contains(x.toLowerCase())));
print(result);
I'm calculating how many different words there are. How can I find the most used word in the text. How can I add this to the code.
int kacFarkliKelime(String metin) {
String yeniMetin = metin.replaceAll(RegExp(r'[^\w\s]+'), "");
List<String> liste = yeniMetin.split(
" ",
);
List farklilar = [];
liste.forEach((element) {
String sorgulanan = element.toLowerCase();
if (!farklilar.contains(sorgulanan)) {
farklilar.add(sorgulanan);
}
});
if(farklilar[0])
return farklilar.length;
}
I'd build a Map<String, int> that'd count each word as it is seen, then get a list of keys sorted by descending value order. (There's a few handy "sort by" functions in package:collection to help with that.) The code for that would look like:
var words = (use a regex to extract words);
var count = <String,int>{};
for (final w in words) {
count[w] = 1 + (count[w] ?? 0);
}
var ordered = count.keys.toList();
ordered.sort((a, b) => count[b].compareTo(count[a]));
Now the first element of ordered is the word with the most appearances in the text.
List listFinal = [];
So listFinal have values from multiple list inside like below.
[["test: 111-333-5555", "test2: 222-333-4555"], ["test3: 555-333-2222"]]
How do I make this list so that it only extract numbers and separate with comma?
End result should be like
[1113335555, 2223334555, 5553332222]
I can think of trimming or regexp but not sure how to pull this off.
many thanks.
Try this
void main() {
List<String> numberList=[];
List<List<dynamic>> demoList=[["test: 111-333-5555", "test2: 222-333-4555"], ["test3: 555-333-2222"]];
for(int i=0;i<demoList.length;i++){
numberList.addAll(demoList[i].map((e) => e.toString().split(":")[1].replaceAll("-", "")).toList());
}
print(numberList.toString());
}
Here is an example to get you started. This doesn't handle things like malformed input strings. First step is to "flatten" the list with .expand, and then for each element of the flattened iterable use a regex to extract the substring. Other options might include using .substring to extract exactly the last 12 characters of the String.
You can see this in action on dartpad.
void main() {
final input = [
['test: 111-333-5555', 'test2: 222-333-4555'],
['test3: 555-333-2222']
];
final flattened = input.expand((e) => e); // un-nest the lists
// call extractNumber on each element of the flattened iterable,
// then collect to a list
final result = flattened.map(extractNumber).toList();
print(result);
}
final _numberRegExp = RegExp(r'.*: ([\d-]+)$');
int extractNumber(String description) {
var numberString = _numberRegExp.firstMatch(description).group(1);
return int.parse(numberString.replaceAll('-', ''));
}
Let's do this in a simple way.
List<List<String>> inputList = [
["test: 111-333-5555", "test2: 222-333-4555"],
["test3: 555-333-2222"]
];
List resultList = [];
print('Input List : $inputList');
inputList.forEach((subList){
subList.forEach((element){
var temp = element.split(' ')[1].replaceAll('-', '');
resultList.add(temp);
});
});
print('Output List : $resultList');
Here I have taken your list as inputList and stored the result in resultList.
For each element of inputList we get a sub-list. I have converted the elements of that sub-list into the needed format and added those into a List.
Happy Coding :)
Is there any way to merge String item in list with another string ?
for example:
I have this list
final list1 = ['Hello'];
i need when click on button add World word to Hello word
so the list will be
['Hello World']
Use
final list1 = ['Hello']; // given
String hello = list1[0]; // get first letter
String world = 'World'; // letter you want to add
list1[0] = hello + ' ' + world; // concatenate both string and update list