Dart print multiple list item at once - list

How can I type something like "print(list[1,4]);" in Dart?
For example:
int main() {
var products = new List(5);
products[0] = "Laptop";
products[1] = "Mouse";
products[2] = "Keyboard";
products[3] = "Monitor";
products[4] = "Microphone";
print(products[1]); // Mouse
print(products[1,3]); // I want to see 'Mouse,Monitor'
}

This is not directly supported in the SDK but you can easily make a extension on e.g. List to add this feature:
void main() {
final products = List<String>(5);
products[0] = "Laptop";
products[1] = "Mouse";
products[2] = "Keyboard";
products[3] = "Monitor";
products[4] = "Microphone";
print(products[1]); // Mouse
print(products.selectMultiple([1,3]).join(',')); // Mouse,Monitor
}
extension MultiSelectListExtension<E> on List<E> {
Iterable<E> selectMultiple(Iterable<int> indexes) sync* {
for (final index in indexes) {
yield this[index];
}
}
}
You can't make it so [1,3] (as in you own example) would be valid since the [] operator does only allow one argument. So instead, we need to make a method which takes our requested indexes as argument.

Related

How to update length of list in dart with default value?

In my app, at many places I have used Lists like this:-
List<int> nums = [];
// initializing list dynamically with some values.
nums.length = 12; // increasing length of list
// setting these values afterward using nums[i] at different places.
Now after migrating to null-safety obviously nums.length = 4 is giving me a runtime error, so I was wondering is there any method to set the length of the list with default values such that, after if the length of the list was smaller than before then with new length extra elements are added with some default value.
Note: Of course I know we can use for loop, but I was just wondering if there is any easier and cleaner method than that.
var num = List<int>.generate(4, (i) => i);
You can read this.
Another approach:
extension ExtendList<T> on List<T> {
void extend(int newLength, T defaultValue) {
assert(newLength >= 0);
final lengthDifference = newLength - this.length;
if (lengthDifference <= 0) {
return;
}
this.addAll(List.filled(lengthDifference, defaultValue));
}
}
void main() {
var list = <int>[];
list.extend(4, 0);
print(list); // [0, 0, 0, 0];
}
Or, if you must set .length instead of calling a separate method, you could combine it with a variation of julemand101's answer to fill with a specified default value instead of with null:
class ExtendableList<T> with ListMixin<T> {
ExtendableList(this.defaultValue);
final T defaultValue;
final List<T> _list = [];
#override
int get length => _list.length;
#override
T operator [](int index) => _list[index];
#override
void operator []=(int index, T value) {
if (index >= length) {
_list.extend(index + 1, defaultValue);
}
_list[index] = value;
}
#override
set length(int newLength) {
if (newLength > length) {
_list.extend(newLength, defaultValue);
} else {
_list.length = newLength;
}
}
}
(I also made its operator []= automatically grow the ExtendableList if the specified index is out-of-bounds, similar to JavaScript.)
Your problem is that the List in Dart does not have the concept of adding more space while you promise that you are not going to use this new capacity before it is set.
But you can easily make your own List implementation which does this:
import 'dart:collection';
void main() {
List<int> nums = ExtendableList();
nums.length = 3;
nums[2] = 1;
nums[0] = 1;
nums[1] = 1;
print(nums); // [1, 1, 1]
nums.add(2);
print(nums); // [1, 1, 1, 2]
print(nums.runtimeType); // ExtendableList<int>
}
class ExtendableList<T> with ListMixin<T> {
final List<T?> _list = [];
#override
int get length => _list.length;
#override
T operator [](int index) => _list[index] as T;
#override
void operator []=(int index, T value) => _list[index] = value;
#override
set length(int newLength) => _list.length = newLength;
}
As you can see we are using a null type behind the scene but from the outside it will work like the list contains non-nullable. This only works because we assume the [] operator will not be called while a null value are in the list (which happens if we extend the list and does not set the value).
I should add that using such a List implementation does comes with great risk since you don't get any warning/error from the analyzer if you are using it wrongly.
You have to use a list of nullable element to make it longer.
List<int?> nums = [];
nums.length = 4; // OK
print(nums); // [null, null, null, null]
You can also use filled method. Here growable is false by default.
void main() {
var a = List<int>.filled(3, 0, growable: true);
print(a);
// [0, 0, 0]
}
Refer: https://api.flutter.dev/flutter/dart-core/List/List.filled.html

Display a chunked items list in Java 8

With the following code:
public class Main {
public static void main(String[] args) {
final List<Integer> items =
IntStream.rangeClosed(0, 23).boxed().collect(Collectors.toList());
final String s = items
.stream()
.map(Object::toString)
.collect(Collectors.joining(","))
.toString()
.concat(".");
System.out.println(s);
}
}
I get:
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23.
What I would like to do, is to break the line every 10 items, in order to get:
0,1,2,3,4,5,6,7,8,9,
10,11,12,13,14,15,16,17,18,19,
20,21,22,23.
I have try a lot of things after googling without any success !
Can you help me ?
Thanks,
Olivier.
If you're open to using a third-party library, the following will work using Eclipse Collections Collectors2.chunk(int).
String s = IntStream.rangeClosed(0, 23)
.boxed()
.collect(Collectors2.chunk(10))
.collectWith(MutableList::makeString, ",")
.makeString("", ",\n", ".");
The result of Collectors2.chunk(10) will be a MutableList<MutableList<Integer>>. At this point I switch from the Streams APIs to using native Eclipse Collections APIs which are available directly on the collections. The method makeString is similar to Collectors.joining(). The method collectWith is like Stream.map() with the difference that a Function2 and an extra parameter are passed to the method. This allows a method reference to be used here instead of a lambda. The equivalent lambda would be list -> list.makeString(",").
If you use just Eclipse Collections APIs, this problem can be simplified as follows:
String s = Interval.zeroTo(23)
.chunk(10)
.collectWith(RichIterable::makeString, ",")
.makeString("", ",\n", ".");
Note: I am a committer for Eclipse Collections.
If all you want to do is process these ascending numbers, you can do it like
String s = IntStream.rangeClosed(0, 23).boxed()
.collect(Collectors.groupingBy(i -> i/10, LinkedHashMap::new,
Collectors.mapping(Object::toString, Collectors.joining(","))))
.values().stream()
.collect(Collectors.joining(",\n", "", "."));
This solution can be adapted to work on an arbitrary random access list as well, e.g.
List<Integer> items = IntStream.rangeClosed(0, 23).boxed().collect(Collectors.toList());
String s = IntStream.range(0, items.size()).boxed()
.collect(Collectors.groupingBy(i -> i/10, LinkedHashMap::new,
Collectors.mapping(ix -> items.get(ix).toString(), Collectors.joining(","))))
.values().stream()
.collect(Collectors.joining(",\n", "", "."));
However, there is no simple and elegant solution for arbitrary streams, a limitation which applies to all kind of tasks having a dependency to the element’s position.
Here is an adaptation of the already linked in the comments Collector:
private static Collector<String, ?, String> partitioning(int size) {
class Acc {
int count = 0;
List<List<String>> list = new ArrayList<>();
void add(String elem) {
int index = count++ / size;
if (index == list.size()) {
list.add(new ArrayList<>());
}
list.get(index).add(elem);
}
Acc merge(Acc right) {
List<String> lastLeftList = list.get(list.size() - 1);
List<String> firstRightList = right.list.get(0);
int lastLeftSize = lastLeftList.size();
int firstRightSize = firstRightList.size();
// they are both size, simply addAll will work
if (lastLeftSize + firstRightSize == 2 * size) {
System.out.println("Perfect!");
list.addAll(right.list);
return this;
}
// last and first from each chunk are merged "perfectly"
if (lastLeftSize + firstRightSize == size) {
System.out.println("Almost perfect");
int x = 0;
while (x < firstRightSize) {
lastLeftList.add(firstRightList.remove(x));
--firstRightSize;
}
right.list.remove(0);
list.addAll(right.list);
return this;
}
right.list.stream().flatMap(List::stream).forEach(this::add);
return this;
}
public String finisher() {
return list.stream().map(x -> x.stream().collect(Collectors.joining(",")))
.collect(Collectors.collectingAndThen(Collectors.joining(",\n"), x -> x + "."));
}
}
return Collector.of(Acc::new, Acc::add, Acc::merge, Acc::finisher);
}
And usage would be:
String result = IntStream.rangeClosed(0, 24)
.mapToObj(String::valueOf)
.collect(partitioning(10));

Search usernames with Regular Expressions

At the moment I'm trying to use a regular expression to find usernames. The following condition is what I need:
"Username matches the search term with a maximum of 3 wrong characters"
For example,
Database content:
"MyUsername"
Search command -> returning match:
search("Username") -> "MyUsername"
search("Us3rname") -> "MyUsername"
search("userName") -> "MyUsername"
search("MyUser") -> none (4 characters wrong)
search("My Us3r N#me") -> none (4 characters wrong)
I can build my regex dynamically and push this to a database query. I only can't get a grip on the regex itself. Could you help me with this? Would be great? (or is it even possible?)
You can't do this with regular expression. You need some similarity algorithm to check the similarity between two strings.
A good start and an easy one is the levensthein distance.
In short: It calculates how many Insert/Update/Delete Operations are needed to transform string A to string B.
I had done this in Javascript some years ago, but it should be easy in nearly every programming language. You can find a working example here:
// http://ejohn.org/blog/fast-javascript-maxmin/
Array.max = function( array ){
return Math.max.apply( Math, array );
};
Array.min = function( array ){
return Math.min.apply( Math, array );
};
// Levenshstein Distance Calculation
function levenshtein_distance (t1, t2) {
var countI = t1.length+1;
var countJ = t2.length+1;
// build empty 'matrix'
var matrix = new Array (countI);
for (var i=0;i<countI;i++) {
matrix[i] = new Array (countJ);
}
// initialize the matrix;
// set m(0,0) = 0;
// m(0,0<=j<countJ) = j
// m(0<=i<countI, 0) = i
matrix[0][0] = 0;
for (var j=1;j<matrix[0].length;j++) {
matrix[0][j] = j;
}
for (var i=1;i<matrix.length;i++) {
matrix[i][0] = i;
}
// calculate the matrix
for (var i=1;i<matrix.length;i++) {
for (var j=1;j<matrix[i].length;j++) {
var costs = new Array ();
if (t1.charAt(i-1) == t2.charAt(j-1)) {
costs.push (matrix[i-1][j-1]);
}
costs.push (matrix[i-1][j-1] + 1);
costs.push (matrix[i][j-1] + 1);
costs.push (matrix[i-1][j] + 1);
matrix[i][j] = Array.min(costs);
}
}
// resultMatrix = matrix;
var result = new Object
result.distance = matrix[countI-1][countJ-1];
result.matrix = matrix;
return result;
}

copy a list to a SpreadSheetGear Irange

I have the following code:
using (CPASEntities ctx = new CPASEntities())
{
IWorksheet ws = wb.Worksheets[0];
ws.Name = "Summary";
var tsm = (from x in ctx.tblTimesheetMasters
where x.TSID == TSID
select new
{
TimesheetID = x.TSID,
Comments = x.TSComments,
Vendor = x.tblVendor.Vendor_Name,
StartDate = x.TSStartDate,
Author = x.TSAuthor,
Approver = x.TSApprover,
Override_Approver = x.TSOverrideApprover,
Status = x.tblTimesheetStatu.TSStatusDesc
}
).ToList();
SpreadsheetGear.IRange range = ws.Cells["A1"];
// I want to copy the entire tsm list to this range, including headings.
}
As the comment states, I want to put that entire list into the ws worksheet starting at A1. I include the code in case it's easier to use a different construct. FWIW, there will be only one entry...TSID is the primary key. I can, of course, use the .FirstorDefault() construct if that is important. I thought it not important.
Your range is only one cell. You need a range big enough to contain all the cells the list would populate.
To populate your worksheet with the list, you could do something like this.
int iRow = 0;
int iCol = 0;
if (tsm.Count() > 0)
{
foreach (var prop in tsm[0].GetType().GetProperties())
{
ws.Cells[iRow, iCol].Value = prop.Name;
iCol++;
}
iRow++;
foreach (var t in tsm)
{
iCol = 0;
foreach (var prop in t.GetType().GetProperties())
{
ws.Cells[iRow, iCol].Value = prop.GetValue(t, null);
iCol++;
}
iRow++;
}
}
If you want a range, you could add this line.
SpreadsheetGear.IRange range = ws.Cells[0, 0, iRow - 1, iCol - 1];

List and Map in java programing

I need to convert:
List<Map>([{1,2},{2,3}])
To:
List<List>([[1,2],[2,3]])
Can anyone help me with example for this ...
Thanks
I would suggest making a list of specific objects instead of a raw list that the get(0) returns the key and get(1) the value as follows:
List<List<Pair>> convert(List<Map<Integer,Integer> mapList){
List<List<Pair>> listOfList = new ArrayList<List<Pair>>();
for(Map<Integer,Integer> map:mapList){
List<Pair> list = new ArrayList<Pair>();
for(Entry<Integer,Integer> e:map.entrySet()){
list.add(Pair(e.getKey(),e.getValue());
}
listOfList.add(list);
}
return listOfList;
}
class Pair{
Integer first;
Integer second;
//constructor
}
You can try the following Code:
import java.util.*;
class ListOfMapToListOfList
{
public static List<List> toList(List<Map<Integer,Integer>> lList)//method to convert List<Map> to List<List>
{
List<List> list = new ArrayList<List>();
for (int i = 0 ; i < lList.size() ; i++)
{
Map<Integer,Integer> map = lList.get(i);
List<Integer> aList = new ArrayList<Integer>();
Set<Integer> keySet = map.keySet();
for (Integer key : keySet)
{
aList.add(key);
aList.add(map.get(key));
}
list.add(aList);
}
return list;
}
public static void main(String[] args) //main body
{
List<Map<Integer,Integer>> list1 = new ArrayList<Map<Integer,Integer>>();
Map<Integer,Integer> map1 = new HashMap<Integer,Integer>();
map1.put(1,2);
Map<Integer,Integer> map2 = new HashMap<Integer,Integer>();
map2.put(1,2);
list1.add(map1);list1.add(map2);
System.out.println(list1);
System.out.println(toList(list1));//Conversion is done here..and out put is shown.
}
}