Concatenate String in Less in Loop

Concatenate String in LESS in loop

You could try passing another attribute to the mixin ... like this, where I added to your code the @t1 to the arguments and define the @t2 in the loop, and pass it on. Now you'll be writing to a variable only in the scope of one loop step, and not trying to overwrite the same variable over again in the recursion (does not agree with less). So this is your code, that should not get the error you mention anymore:

    @test: "";

.populateGridClasses4 (@index, @interval, @t1) when (@index > 0) {
@num: @index * @interval;
@ntest: ".eh-grid-@{num}, .eh-mobile-grid-@{num}, .eh-tablet-grid-@{num}";
@t2: ~"@{t1}@{ntest}";
.populateGridClasses4(@index - 1, @interval,@t2);
}

.populateGridClasses4 (0, @interval,@t1) {}

.populateGridClasses4(20, 5, @test);

@{t2} {
padding-left: 1px;
}

Also you need use ~ for class interpolation, not to return the class names between quotation marks.

Edit: The above will only work in 1.3.3, but for your approach to work in 1.4 you need to tweak it a little. Also I noticed that the way you were joining the strings did not add commas between class names of each loop, so I added another step here, this should now do the right thing in1.4 and previous versions of LESS.

    .populateGridClasses4(1,@num,@t1) {
@test: ~"@{t1}, .eh-grid-@{num}, .eh-mobile-grid-@{num}, .eh-tablet-grid-@{num}";
}

.populateGridClasses4(@index, @interval, @t1) when (@index > 1) {
@num: (@index * @interval);
@t2: "@{t1}, .eh-grid-@{num}, .eh-mobile-grid-@{num}, .eh-tablet-grid-@{num}";
.populateGridClasses4((@index - 1),@interval,@t2);
}

.populateGridClasses4(@index,@interval) {
@num: (@index * @interval);
@t2: ".eh-grid-@{num}, .eh-mobile-grid-@{num}, .eh-tablet-grid-@{num}";
.populateGridClasses4((@index - 1), @interval, @t2);
}

.populateGridClasses4(20, 5);
@{test} { padding-left: 1px; }

the output CSS is:

  .eh-grid-100, .eh-mobile-grid-100, .eh-tablet-grid-100, .eh-grid-95, .eh-mobile-grid-95, .eh-tablet-grid-95, .eh-grid-90, .eh-mobile-grid-90, .eh-tablet-grid-90, .eh-grid-85, .eh-mobile-grid-85, .eh-tablet-grid-85, .eh-grid-80, .eh-mobile-grid-80, .eh-tablet-grid-80, .eh-grid-75, .eh-mobile-grid-75, .eh-tablet-grid-75, .eh-grid-70, .eh-mobile-grid-70, .eh-tablet-grid-70, .eh-grid-65, .eh-mobile-grid-65, .eh-tablet-grid-65, .eh-grid-60, .eh-mobile-grid-60, .eh-tablet-grid-60, .eh-grid-55, .eh-mobile-grid-55, .eh-tablet-grid-55, .eh-grid-50, .eh-mobile-grid-50, .eh-tablet-grid-50, .eh-grid-45, .eh-mobile-grid-45, .eh-tablet-grid-45, .eh-grid-40, .eh-mobile-grid-40, .eh-tablet-grid-40, .eh-grid-35, .eh-mobile-grid-35, .eh-tablet-grid-35, .eh-grid-30, .eh-mobile-grid-30, .eh-tablet-grid-30, .eh-grid-25, .eh-mobile-grid-25, .eh-tablet-grid-25, .eh-grid-20, .eh-mobile-grid-20, .eh-tablet-grid-20, .eh-grid-15, .eh-mobile-grid-15, .eh-tablet-grid-15, .eh-grid-10, .eh-mobile-grid-10, .eh-tablet-grid-10, .eh-grid-5, .eh-mobile-grid-5, .eh-tablet-grid-5 {
padding-left: 1px;
}

Concatenate string through for loop

Don't declare a new str variable inside the loop with var str. Reuse the one you declare outside the loop. Also do +=

var divLength = $('div').length;

var str = '';
for(var i = 0; i < divLength; i++) {
str += "Div #" + i + ", ";
console.log(str);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div></div>
<div></div>
<div></div>
<div></div>

Python string concatenation loop

I can be fairly confident your test methodology is invalid, as can be demonstrated by repl.it for Py2.7 and repl.it for Py3. It's the same code, as shown below, but the results vary:

f1 is your f1 function

f2 is your f2 function

f3 is your f2 function using c-style string formatting "%s" % str
f4 is your f2 function using .format()

Results:

Python 2.7.10 (default, Jul 14 2015, 19:46:27)
[GCC 4.8.2] on linux

1.67547893524
1.33767485619
0.72606086731
1.32540607452

There are some differences, but in no case does f1 outperform any of the following methods.

Python 3.6.1 (default, Dec 2015, 13:05:11)
[GCC 4.8.2] on linux

3.0050943629757967
2.016791722999187
0.9476796620001551
1.9396837950043846

In both cases c style strings formatting is more than twice as fast.

The functions used:

def f1():
s = ''
for i in range(len(values)):
s += str(values[i][0])
s += '\t'
s += str(values[i][1])
s += '\r\n'
return s

def f2():
return ''.join((
str(ts) + '\t' + str(v) + '\r\n'
for ts, v in values))

def f3():
return ''.join((
"%s\t%s\r\n" % (ts, v)
for ts, v in values))

def f4():
return ''.join((
"{}\t{}\r\n".format(ts, v)
for ts, v in values))

Interestingly, by making a small change to your f1 function, we can attain a decent speed up by exploiting the bytecode speedup referenced by danny:

def f1opt():
s = ''
for i in range(len(values)):
s += str(values[i][0]) + '\t' + str(values[i][1]) + '\r\n'
return s

yields

Python 2.7.10 (default, Jul 14 2015, 19:46:27)
[GCC 4.8.2] on linux

f1() 1.68486714363
f1bytecode() 0.999644994736

LESS variable self concatenation

Yes, essentially, it is possible, though not on the same scope. I've ended up with recursive approach like this


.concat-test {
.concat(@rest...) {
._concat(@i, @result, @rest...) {
@var: extract(@rest, @i);
.-() when (@i > length(@rest)) {
@concat: @result;
}
.-() when (default()) {
._concat(@i+1, ~"@{result}@{var}", @rest);
}
.-();
}
._concat(1, "", @rest);
}

@a:a;
@b:b;
@c:c;

.concat(@a, @b, @c, @b, @a);
concat: @concat;
}

Appending a string in a loop in effective way

Use string.Join() and a Linq projection with Select() instead:

finalString = string.Join("|", EmployeeList.Select( x=> x.Name));

Three reasons why this approach is better:

  1. It is much more concise and readable
    – it expresses intend, not how you
    want to achieve your goal (in your

    case concatenating strings in a
    loop). Using a simple projection with Linq also helps here.

  2. It is optimized by the framework for
    performance: In most cases string.Join() will
    use a StringBuilder internally, so
    you are not creating multiple strings that are
    then un-referenced and must be
    garbage collected. Also see: Do not
    concatenate strings inside loops

  3. You don’t have to worry about special cases. string.Join()
    automatically handles the case of
    the “last item” after which you do
    not want another separator, again
    this simplifies your code and makes
    it less error prone.

loop concatenation using .concat without using just loop

Few Changes.

1.) looping was not correct.

should be as below, if num > 1 then concatenate in loop.

 if (num > 1) {
for (int i = 0 ; i < num ; i++) {
finish = finish.concat(state);
}
} else {
finish = finish.concat(state);
}

2.) finish.concat(state) returns a new String, so you have to assign in to the finish variable

finish = finish.concat(state); // **remember Strings are immutable**

Complete program

public class multiConcat {
public static void main(String[] args) {
int num = 0;
String finish = "";
Scanner reader = new Scanner(System.in);

System.out.println("Type a word: ");
String state = reader.next();
System.out.println("Number of Concatenation: ");
num = reader.nextInt();

if (num > 1) {
for (int i = 0 ; i < num ; i++) {
finish = finish.concat(state);
}
} else {
finish = finish.concat(state);
}

System.out.println(finish);

}
}

output

Type a word: 
ankur
Number of Concatenation:
2
ankurankur

Type a word:
ankur
Number of Concatenation:
1
ankur

Type a word:
ankur
Number of Concatenation:
3
ankurankurankur


Related Topics



Leave a reply



Submit