This question already has answers here:
How do I split or chunk a list into equal parts, with Dart?
(21 answers)
Closed 10 months ago.
I have a list of Strings and an integer.
int number = 3;
var items = ['foo', 'hey','yo','bar', 'baz', 'qux'];
How can I split this list by the number(number of Lists to output).
Output :
List 1 = ['foo', 'hey']
List 2 = ['yo', 'bar']
List 3 = ['baz', 'qux']
void main(List<String> args) {
var n = 3;
var items = ['foo', 'hey','yo','bar', 'baz', 'qux'];
var m = (items.length / n).round();
var lists = List.generate(n, (i) => items.sublist(m*i, (i+1)*m <= items.length ? (i+1)*m : null));
print(lists);
}
Result:
[[foo, hey], [yo, bar], [baz, qux]]
Returns a new list containing the elements between start and end.
The new list is a List<E> containing the elements of this list at positions greater than or equal to start and less than end in the same order as they occur in this list.
var colors = ["red", "green", "blue", "orange", "pink"];
print(colors.sublist(1, 3)); // [green, blue]
If end is omitted, it defaults to the length of this list.
print(colors.sublist(1)); // [green, blue, orange, pink]
The start and end positions must satisfy the relations 0 ≤ start ≤ end ≤ this.length If end is equal to start, then the returned list is empty.
Implementation
List<E> sublist(int start, [int? end]);
Related
I have a list of custom data objects which track an increasing total value on a daily basis using one field total. Another field in the custom data type is the value new. Using a csv file I have read in the values for date and total and am trying to calculate and set the values for new from these values.
data item = Item{
date :: Day,
total :: Int,
new :: Int
}
Before
date
total
new
01/01/2021
0
0
02/01/2021
2
0
03/01/2021
6
0
04/01/2021
15
0
After
date
total
new
01/01/2021
0
0
02/01/2021
2
2
03/01/2021
6
4
04/01/2021
15
9
My understanding is that in haskell I should be trying to avoid the use of for loops which iterate over a list until the final row is reached, for example using a loop control which terminates upon reaching a value equal to the length of the list.
Instead I have tried to create a function which assigns the value of new which can used with map to update each item in the list. My problem is that such a function requires access to both the item being updated, as well as the previous item's value for total and I'm unsure how to implement this in haskell.
--Set daily values by mapping single update function across list
calcNew:: [Item] -> Int -> [Item]
calcNew items = map updateOneItem items
-- takes an item and a value to fill the new field
updateOneItem :: Item -> Int -> Item
updateOneItem item x = Item date item total item x
Is it possible to populate that value while using map? If not, is a recursive solution required?
We can do this by zipping the input list with itself, shifted by one step.
Assuming you have a list of items already populated with total values, which you want to update to contain the correct new values (building an updated copy of course),
type Day = Int
data Item = Item{ -- data Item, NB
date :: Day,
total :: Int,
new :: Int
} deriving Show
calcNews :: [Item] -> [Item]
calcNews [] = []
calcNews totalsOK#(t:ts) = t : zipWith f ts totalsOK
where
f this prev = this{ new = total this - total prev }
This gives us
> calcNews [Item 1 0 0, Item 2 2 0, Item 3 5 0, Item 4 10 0]
[Item {date = 1, total = 0, new = 0},Item {date = 2, total = 2, new = 2},
Item {date = 3, total = 5,new = 3},Item {date = 4, total = 10, new = 5}]
Of course zipWith f x y == map (\(a,b) -> f a b) $ zip x y, as we saw in your previous question, so zipWith is like a binary map.
Sometimes (though not here) we might need access to the previously calculated value as well, to calculate the next value. To arrange for that we can create the result by zipping the input with the shifted version of the result itself:
calcNews2 :: [Item] -> [Item]
calcNews2 [] = []
calcNews2 (t:totalsOK) = newsOK
where
newsOK = t : zipWith f totalsOK newsOK
f tot nw = tot{ new = total tot - total nw }
Is there a way to get 4 instead of 2 as a result?
List<String> test = [
'first',
'second',
if (false) 'third',
if (false) 'fourth',
];
print('length: ' + test.length.toString());
The length property on lists returns the number of elements in the list. In you example you are only inserting two values (because of the condition) so a length of 4 would not make sense and would give problems when you e.g. want to iterate over the list.
You can however add null elements if the condition are false like this:
void main() {
List<String> list = [
'first',
'second',
(false) ? 'third' : null,
(false) ? 'fourth' : null,
];
final listLengthIncludingConditions = list.length;
list.removeWhere((x) => x != null);
print('Number of possible elements in list: $listLengthIncludingConditions'); // 4
print('Number of elements in list: ${list.length}'); // 2
}
You can then save the length and remove the null elements.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
my question is the following: I have a file which contains around 70 strings, all of them have 6 characters (either a,c,g or t for every position -> these are short DNA-sequences).
For example:
accggt agctta gggatc gactta ccttgg
What I need are the strings which are completely unique. Which have on every position a different character (base) compared with the other strings.
In this case I would get two matches (I define them as lists but this is only an idea for the output format):
[accggt , gggatc]
[gggatc , ccttgg]
The elements of list one are on every position different and so are also the elements of list 2.
Is there a build-in function which can do it? I also thought of regular expression but I'm not that familar with this approach.
Thanks in advance!
Edit:
Ok, it seems it is not that easy to describe. So lets go into more detail:
Let's take the five strings mentioned above:
I would start to compare the first string with all the other strings and then continue with string 2 comparing with all other strings and so on.
The first character of the first string is an a.
The first character of the second string is also an a.
This means I would discard the second string.
The first character of the third string is an g.
Fine.
The second character of the first string is an c.
The second character of the third string is an g.
Fine.
The third character of the first string is an c.
The third character of the third string is an g.
Fine.
The fourth ... and so on.
And if all characters of a string are different from the characters of another string (on every position like described above) I would keep those two strings and would search for the next strings which are different on every position compared to the strings I already found. Because I only have four letters there should be only four possibilities fo different strings.
I should end up with, probably a list, which contains the groups of strings which are different in every position.
I hope this helps.
You can use the following algorithm: iterate through all possible word combinations in your string and check each pair for equality with if [x == y for (x, y) in zip(word, nextWord)].count(True) == 0:.
Here is a snippet:
s = "accggt agctta gggatc gactta ccttgg"
chks = s.split(" ");
for word in chks:
for nextWord in chks:
if word != nextWord:
if [x == y for (x, y) in zip(word, nextWord)].count(True) == 0:
print([word, nextWord])
Result of the IDEONE demo:
['accggt', 'gggatc']
['gggatc', 'accggt']
['gggatc', 'ccttgg']
['ccttgg', 'gggatc']
UPDATE
You can deduplicate the list with a custom function. Here is an updated snippet:
def dedup(lst):
seen = set()
result = []
for item in lst:
fs = frozenset(item)
if fs not in seen:
result.append(item)
seen.add(fs)
return result
res = []
s = "accggt agctta gggatc gactta ccttgg"
chks = s.split(" ");
for word in chks:
for nextWord in chks:
if word != nextWord:
if [x == y for (x, y) in zip(word, nextWord)].count(True) == 0:
res.append([word, nextWord])
print(dedup(res))
Result: [['accggt', 'gggatc'], ['gggatc', 'ccttgg']].
To check the words by 3, you need to create all possible permutations of the string into 3-word combinations and use something like:
from itertools import permutations
def dedup(lst):
seen = set()
result = []
for item in lst:
fs = frozenset(item)
if fs not in seen:
result.append(item)
seen.add(fs)
return result
res = []
s = "accggt agctta gggatc gactta ccttgg"
chks = s.split(" ");
perms = [p for p in permutations(chks, 3)]
for perm in perms:
if [(x == y or y == z or x == z) for (x, y, z) in zip(*perm)].count(True) == 0:
res.append(perm)
print(dedup(res))
To find the DNA strings which are completely different on every character you have to check every string against any other string if any character of the given string is the same character on the same position in the comparing string.
Here is an example code for that:
# read all dna strings into a list of strings
dna = ['accggt', 'agctta', 'gggatc', 'gactta', 'ccttgg', '123456']
def compare_two_dna(dna1, dna2):
i = 0
l = len(dna1)
while(i < l):
if dna1[i] == dna2[i]:
return True
i += 1
return False
def is_dna_unique(d, dna_strings):
return len(filter(lambda x: compare_two_dna(d, x), dna_strings)) == 1
# filter all items which only occure once in the list
unique_dna = filter(lambda d: is_dna_unique(d, dna), dna)
print(unique_dna)
The result here is: 123456
var dnaList = "accggt agctta gggatc gactta ccttgg".split( " " );
function getUniqueDnas( dna_list ){
var result = [];
for( var d1 in dna_list ){
var isRepeat = false;
var dna1 = dna_list[ d1 ];
for( var d2 in dna_list ){
var dna2 = dna_list[ d2 ];
if( dna1 == dna2 ){
isRepeat = true;
break;
}
}
if( !isRepeat )
result.push( dna1 );
}
return result;
}
var uniqueDnaList = getUniqueDnas( dnaList );
I'm developing my first application with Dart, which had previously created in JavaScript.
In my statement in JavaScript I have declared a List, and I assign values to the first three positions, as seen here:
serpF var = new List ();
serpF [0] = 10;
serpF [1] = 10;
serpF [2] = 10;
How I can do the same in Dart? I have read the documentation of Lists and Arrays of Seth Ladd in "http://blog.sethladd.com/2011/12/lists-and-arrays-in-dart.html" and I've tried everything, but it is being impossible.
The javaScript code does not work in Dart because it is an error to access past the end of the List. Dart is like many other languages as this is a way to catch logic errors.
What you can do is add elements to a List:
var serpF = new List(); // This list has length == 0.
serpF.add(10);
serpF.add(10);
serpF.add(10);
You can use method cascades to shorten the code:
var serfP = [];
serpF..add(10)..add(10)..add(10);
If you do know the length, you might also try one of the other List constructors:
var serfP = new List.filled(3, 10);
var serfP = new List.generate(3, (i) => 10);
I addition to what Stephen suggests you can also do:
var serpF = [10, 10, 10];
or
var serpF = new List();
serpF.length = 3;
serpF[0] = 10;
serpF[1] = 10;
serpF[2] = 10;
You can also use the List.generate() constructor:
var list = new List.generate(3, (_) => 10, growable: true);
print(list); // Prints [10, 10, 10].
The first arg specifies the number of elements in the list, the second arg takes a callback to give each element a value, and the third arg ensures that the list is not fixed-width.
I'm looking every where on the web (dart website, stackoverflow, forums, etc), and I can't find my answer.
So there is my problem: I need to write a function, that print a random sort of a list, witch is provided as an argument. : In dart as well.
I try with maps, with Sets, with list ... I try the method with assert, with sort, I look at random method with Math on dart librabry ... nothing can do what I wana do.
Can some one help me with this?
Here some draft:
var element03 = query('#exercice03');
var uneliste03 = {'01':'Jean', '02':'Maximilien', '03':'Brigitte', '04':'Sonia', '05':'Jean-Pierre', '06':'Sandra'};
var alluneliste03 = new Map.from(uneliste03);
assert(uneliste03 != alluneliste03);
print(alluneliste03);
var ingredients = new Set();
ingredients.addAll(['Jean', 'Maximilien', 'Brigitte', 'Sonia', 'Jean-Pierre', 'Sandra']);
var alluneliste03 = new Map.from(ingredients);
assert(ingredients != alluneliste03);
//assert(ingredients.length == 4);
print(ingredients);
var fruits = <String>['bananas', 'apples', 'oranges'];
fruits.sort();
print(fruits);
There is a shuffle method in the List class. The methods shuffles the list in place. You can call it without an argument or provide a random number generator instance:
var list = ['a', 'b', 'c', 'd'];
list.shuffle();
print('$list');
The collection package comes with a shuffle function/extension that also supports specifying a sub range to shuffle:
void shuffle (
List list,
[int start = 0,
int end]
)
Here is a basic shuffle function. Note that the resulting shuffle is not cryptographically strong. It uses Dart's Random class, which produces pseudorandom data not suitable for cryptographic use.
import 'dart:math';
List shuffle(List items) {
var random = new Random();
// Go through all elements.
for (var i = items.length - 1; i > 0; i--) {
// Pick a pseudorandom number according to the list length
var n = random.nextInt(i + 1);
var temp = items[i];
items[i] = items[n];
items[n] = temp;
}
return items;
}
main() {
var items = ['foo', 'bar', 'baz', 'qux'];
print(shuffle(items));
}
You can use shuffle() with 2 dots like Vinoth Vino said.
List cities = ["Ankara","London","Paris"];
List mixed = cities..shuffle();
print(mixed);
// [London, Paris, Ankara]