I recently started learning Kotlin and the one thing I noticed is the for-loop syntax of Kotlin is different from traditional for-loop syntax and for me it is a bit confusing...I tried to search it on google but didn't get my answer.
How would I duplicate the following Java for loop?
for (int i = 0; i <= 100; i++) {
System.out.println(i);
}
Here is a Java for loop to iterate 100 times:
for (int i = 0; i <= 100; i++) {
System.out.println(i);
}
Here is the Kotlin equivalent:
for (i in 0..100) {
println(i)
}
Here is a Java for loop that will iterate through a list:
for (int i = 0; i < list.size(); i++) {
Object item = list.get(i);
// Do something with item
}
Kotlin equivalent:
for (i in list.indices) {
val item = list[i]
// Do something with item
}
Here is another Kotlin equivalent for iterating a list:
for (i in 0 until list.size) {
val item = list[i]
// Do something with item
}
Java for-each loop:
for (Object item : list) {
// Do something with item
}
Kotlin for-each loop:
for (item in list) {
// Do something with item
}
val scanner = Scanner(System.`in`)
var nos = Array<Int>(5) { 0 }
for (i in 1..3) {
nos[i] = scanner.nextInt()
}
println("Given values $nos")
Here, you can see i in 1..3 and you do not need to declare var i : Int = 1 as it'll be declared for you in the loop. Nor do you need the i = i+1 inside the loop for that matter.
Related
CODE
void main() {
List<String> str = ["hello", "world"];
for (int i = 0; i < str.length; i++) {
for (int j = 0; j < str[i].length; j++) {
if (str[i][j] == 'o') {
str[i][j]='e';
print('$i,$j');
}
}
}
print(str);
}
The Error I get
The operator '[]=' isn't defined for the class 'String'.
Try correcting the operator to an existing operator, or defining a '[]=' operator.
str[i][j]='e';
If i comment this line //str[i][j]='e'; i get the location of the characters but i am unable to edit the string like we usually do in C++
String in Dart does not have a []= operator which means you cannot set a value on the String using the [] operator like you are trying to do.
This makes sense since String is immutable in Dart and calling the []= does not allow us to return anything, so we would not be able to get the modified String back.
We can instead call .replaceRange() on the String which allow us to replace a part of a String with some other String value. The method will return a new String with the change (since we are not allowed to change any existing String object).
With this, we can rewrite your example to:
void main() {
List<String> str = ["hello", "world"];
for (int i = 0; i < str.length; i++) {
for (int j = 0; j < str[i].length; j++) {
if (str[i][j] == 'o') {
str[i] = str[i].replaceRange(j, j + 1, 'e');
print('$i,$j');
}
}
}
print(str);
}
Which will output:
0,4
1,1
[helle, werld]
If the purpose is to replace all o with e, a more efficient solution would be to use the replaceAll() method:
void main() {
List<String> str = ["hello", "world"];
for (int i = 0; i < str.length; i++) {
str[i] = str[i].replaceAll('o', 'e');
}
print(str); // [helle, werld]
}
Simple way: Map and replaceAll
List<String> str = ["hello","world"];
str = str.map((s)=>
s.replaceAll("o", "e")
).toList();
print(str);
Result
I am new to Revit API and am working in C#. I want to get the schedule element parameters value using C#. I used the below code to get the view schedule.
var viewSchedule = new FilteredElementCollector(document)
.OfClass(typeof(ViewSchedule))
.FirstOrDefault(e => e.Name == "MyScheduleName") as ViewSchedule;
Schedule Element Data
From the above schedule, I used the below code to get the element data (please refer the above screenshot link) but it taking long time to reflect the output (10 to 15 seconds).
var rowCount = viewSchedule.GetTableData().GetSectionData(SectionType.Body).NumberOfRows;
var colCount = viewSchedule.GetTableData().GetSectionData(SectionType.Body).NumberOfColumns;
for (int i = 0; i < rowCount; i++)
{
for (int j = 0; j < colCount; j++)
{
data += viewSchedule.GetCellText(SectionType.Body, i, j);
}
}
Please let me know is there any alternate approach to get the schedule data using C#.
Thanks in advance.
Maybe you can also use ViewSchedule.Export as demonstrated by The Building Coder discussing The Schedule API and Access to Schedule Data.
Yes, you can easily access Schedule data without exporting.
Firstly, get all the schedules and read the data cell by cell. Secondly, create dictionary and store data in form of key, value pairs. Now you can use the schedule data as you want. I have tried this in Revit 2019.
Here is the implementation.
public void getScheduleData(Document doc)
{
FilteredElementCollector collector = new FilteredElementCollector(doc);
IList<Element> collection = collector.OfClass(typeof(ViewSchedule)).ToElements();
String prompt = "ScheduleData :";
prompt += Environment.NewLine;
foreach (Element e in collection)
{
ViewSchedule viewSchedule = e as ViewSchedule;
TableData table = viewSchedule.GetTableData();
TableSectionData section = table.GetSectionData(SectionType.Body);
int nRows = section.NumberOfRows;
int nColumns = section.NumberOfColumns;
if (nRows > 1)
{
//valueData.Add(viewSchedule.Name);
List<List<string>> scheduleData = new List<List<string>>();
for (int i = 0; i < nRows; i++)
{
List<string> rowData = new List<string>();
for (int j = 0; j < nColumns; j++)
{
rowData.Add(viewSchedule.GetCellText(SectionType.Body, i, j));
}
scheduleData.Add(rowData);
}
List<string> columnData = scheduleData[0];
scheduleData.RemoveAt(0);
DataMapping(columnData, scheduleData);
}
}
}
public static void DataMapping(List<string> keyData, List<List<string>>valueData)
{
List<Dictionary<string, string>> items= new List<Dictionary<string, string>>();
string prompt = "Key/Value";
prompt += Environment.NewLine;
foreach (List<string> list in valueData)
{
for (int key=0, value =0 ; key< keyData.Count && value< list.Count; key++,value++)
{
Dictionary<string, string> newItem = new Dictionary<string, string>();
string k = keyData[key];
string v = list[value];
newItem.Add(k, v);
items.Add(newItem);
}
}
foreach (Dictionary<string, string> item in items)
{
foreach (KeyValuePair<string, string> kvp in item)
{
prompt += "Key: " + kvp.Key + ",Value: " + kvp.Value;
prompt += Environment.NewLine;
}
}
Autodesk.Revit.UI.TaskDialog.Show("Revit", prompt);
}
I want to iterate through a String with condition to skip 2 or more characters in 1 iteration. An example code in C++
// str = "123"
for (int i = 0; i < str.size(), i++) {
if (str[i] == '2') {
// do something
i++;
}
// do something
}
My Swift version is like this, but after the iteration finishs, there is an error saying:
"fatal error: Can't form a Character from an empty String"
// str = "123"
for var index = str.startIndex; index != str.endIndex; index = index.advancedBy(1) {
if (str[index] == "2") {
// do something
index = index.advancedBy(1)
}
// do something
}
I guess this is the place I got wrong, "index != str.endIndex"
How to fix it or any alternative way to achieve this?
I understand that currently Dart doesn't have an explicit way to remove objects from memory and that objects that are no longer referenced anywhere are removed automatically.
Yet I've been running some benchmarking. Here's the code:
import 'dart:html';
import 'dart:async';
var components = [];
var times_to_run = 10;
class MockComponent {
Element element = new Element.html('<table></table>');
remove() {
element.remove();
element = null;
}
}
createAndRemoveComponents(t) {
var n = 50000; // number of objects to create and delete in this run
print("***Run #${times_to_run}");
print("creating $n objects...");
for(var i=0; i < n; i++) {
components.add(new MockComponent());
}
print("...done");
print("removing $n objects...");
while(components.length > 0) {
components.removeAt(0).remove();
}
print("...done");
times_to_run -= 1;
if(times_to_run <= 0) {
components = null;
t.cancel();
}
}
void main() {
new Timer.periodic(const Duration(seconds: 10), createAndRemoveComponents);
}
I made a video of this code running, so please take a look and see for yourself that memory actually leaks: http://www.youtube.com/watch?v=uVD8Npvc9vQ
This is a project I'm doing for my own amusement.
I started out wanting to experiment with combination and permutations. In a console application I have the following code
public static void Save(string newWord)
{
using (var db = new MyDataContext())
{
var w = new Word {word = newWord};
db.Words.InsertOnSubmit(w);
db.SubmitChanges();
}
}
static void Main(string[] args)
{
var letters = new[] { 'A', 'B', 'C', '1', '2', '3'};
for (var i = 2; i < 10; i++)
{
letters.GetPermutations(a => Save(string.Join(string.Empty, a.ToArray())), i, true);
}
}
In an extension class, I have the code to generate the combinations. I found the code for the combinations here (http://blog.noldorin.com/2010/05/combinatorics-in-csharp/) for those wanting to review that.
public static void GetCombinations<T>(this IList<T> list, Action<IList<T>> action, int? resultSize = null, bool withRepetition = false)
{
if (list == null)
throw new ArgumentNullException("list");
if (action == null)
throw new ArgumentNullException("action");
if (resultSize.HasValue && resultSize.Value <= 0)
throw new ArgumentException(errorMessageValueLessThanZero, "resultSize");
var result = new T[resultSize.HasValue ? resultSize.Value : list.Count];
var indices = new int[result.Length];
for (int i = 0; i < indices.Length; i++)
indices[i] = withRepetition ? -1 : indices.Length - i - 2;
int curIndex = 0;
while (curIndex != -1)
{
indices[curIndex]++;
if (indices[curIndex] == (curIndex == 0 ? list.Count : indices[curIndex - 1] + (withRepetition ? 1 : 0)))
{
indices[curIndex] = withRepetition ? -1 : indices.Length - curIndex - 2;
curIndex--;
}
else
{
result[curIndex] = list[indices[curIndex]];
if (curIndex < indices.Length - 1)
curIndex++;
else
action(result);
}
}
}
Then I thought it would be cool to calculate the combinations for all charaters in a list, each in its own thread. So in my for/next loop, I tried
Thread t = new Thread(letters.GetPermutations(a => Save(string.Join(string.Empty, a.ToArray())), i, true));
But apparently, the Action that is being passed in, the call to the 'Save' function, is not liked in the Thread. If someone could give me a nudge in the right direction, I'd appreciate it.
Thanks,
Andy
The Thread constructor is looking for a delegate but you're appearing to pass a value instead. Try wrapping it in an ThreadStart delegate.
ThreadStart del = () => letters.GetPermutations(a => Save(string.Join(string.Empty, a.ToArray())), i, true);
Thread t = new Thread(del);
t.Start();