What is the meaning of "Object [RegExp String Iterator] {}" in NodeJs - node.js

I've been trying use matchAll in node.js, but when I run the code and log the return value it only shows Object [RegExp String Iterator] {}.
Could you help me to understand why this is the case?

Be mindful of the types of things you are working with.
To quote the docs for String.prototype.matchAll:
The matchAll() method returns an iterator of all results matching a string against a regular expression, including capturing groups.
(Emphasis mine.)
So, you get an iterator. What is an iterator? Well, the docs say:
In JavaScript an iterator is an object which defines a sequence and potentially a return value upon its termination.
[...]
While it is easy to imagine that all iterators could be expressed as arrays, this is not true. Arrays must be allocated in their entirety, but iterators are consumed only as necessary. Because of this, iterators can express sequences of unlimited size, such as the range of integers between 0 and Infinity.
So, matchAll will only do the actual work of finding the next match when you ask for it, by asking for next value of the iterator, and the amount of state that has to be kept won't increase that much with a longer string because not all matches have to be remembered at once. That's the beauty of iterators (and their opposite part, generators).
This is also why you won't see all the results in your console when printing the iterator - otherwise, a matchAll on a very very large string would cause a long delay and high CPU usage when its return value is merely logged to the console, which wouldn't make sense.
You can use the result of matchAll in a for of loop, which will look for the next match every time the loop repeats:
for (const match of 'abcde'.matchAll(/./g)) {
console.log(match)
}
// Prints 5 times something like ['a', index: 0, input: 'abcde', groups: undefined ]
Or, if you are willing to forgo the benefit of on-demand matching, you can extract all values from the iterator at once and fit them into an array using either spread syntax or Array.from:
const allMatches = [...'abcde'.matchAll(/./g)]
// - or -
const allMatches = Array.from('abcde'.matchAll(/./g))
(In fact, the spread syntax is shown in the example at the very top of the matchAll docs too.)

Related

kotlin string concatenation no side effect

Why is string concatenation kept without side-effects?
fun main() {
var s1 = "abc"
val s2 = "def"
s1.plus(s2)
println(s1)
// s1 = s1.plus(s2)
// println(s1)
}
I expected abcdef, but got just abc. The commented code works fine, but seems awkward.
The plus() method (or the + operator, which is basically the same thing in kotlin) is returning the concatenated string. So by calling
s1.plus(s2)
//or
s1 + s2
you concatenate these strings but you throw away the result.
As this answer shows. Your plus operation returns the concatenated string independent from the given strings. This is because strings are immutable in Kotlin. An alternative is to use CharLists or buffers.
Note that immutability has some serious benefits. With immutablility it is no problem to give away your references to immutable objects because nobody can change the object. You need to change the reference in your model to hold a new value. This way it helps a lot to guarantee consistency and integrity in your model. Also note that immutable objects are threadsafe for that reason.

TypeError when applying sum to a list of strings [duplicate]

Closed. This question is opinion-based. It is not currently accepting answers.
Closed 4 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
Python has a built in function sum, which is effectively equivalent to:
def sum2(iterable, start=0):
return start + reduce(operator.add, iterable)
for all types of parameters except strings. It works for numbers and lists, for example:
sum([1,2,3], 0) = sum2([1,2,3],0) = 6 #Note: 0 is the default value for start, but I include it for clarity
sum({888:1}, 0) = sum2({888:1},0) = 888
Why were strings specially left out?
sum( ['foo','bar'], '') # TypeError: sum() can't sum strings [use ''.join(seq) instead]
sum2(['foo','bar'], '') = 'foobar'
I seem to remember discussions in the Python list for the reason, so an explanation or a link to a thread explaining it would be fine.
Edit: I am aware that the standard way is to do "".join. My question is why the option of using sum for strings was banned, and no banning was there for, say, lists.
Edit 2: Although I believe this is not needed given all the good answers I got, the question is: Why does sum work on an iterable containing numbers or an iterable containing lists but not an iterable containing strings?
Python tries to discourage you from "summing" strings. You're supposed to join them:
"".join(list_of_strings)
It's a lot faster, and uses much less memory.
A quick benchmark:
$ python -m timeit -s 'import operator; strings = ["a"]*10000' 'r = reduce(operator.add, strings)'
100 loops, best of 3: 8.46 msec per loop
$ python -m timeit -s 'import operator; strings = ["a"]*10000' 'r = "".join(strings)'
1000 loops, best of 3: 296 usec per loop
Edit (to answer OP's edit): As to why strings were apparently "singled out", I believe it's simply a matter of optimizing for a common case, as well as of enforcing best practice: you can join strings much faster with ''.join, so explicitly forbidding strings on sum will point this out to newbies.
BTW, this restriction has been in place "forever", i.e., since the sum was added as a built-in function (rev. 32347)
You can in fact use sum(..) to concatenate strings, if you use the appropriate starting object! Of course, if you go this far you have already understood enough to use "".join(..) anyway..
>>> class ZeroObject(object):
... def __add__(self, other):
... return other
...
>>> sum(["hi", "there"], ZeroObject())
'hithere'
Here's the source: http://svn.python.org/view/python/trunk/Python/bltinmodule.c?revision=81029&view=markup
In the builtin_sum function we have this bit of code:
/* reject string values for 'start' parameter */
if (PyObject_TypeCheck(result, &PyBaseString_Type)) {
PyErr_SetString(PyExc_TypeError,
"sum() can't sum strings [use ''.join(seq) instead]");
Py_DECREF(iter);
return NULL;
}
Py_INCREF(result);
}
So.. that's your answer.
It's explicitly checked in the code and rejected.
From the docs:
The preferred, fast way to concatenate a
sequence of strings is by calling
''.join(sequence).
By making sum refuse to operate on strings, Python has encouraged you to use the correct method.
Short answer: Efficiency.
Long answer: The sum function has to create an object for each partial sum.
Assume that the amount of time required to create an object is directly proportional to the size of its data. Let N denote the number of elements in the sequence to sum.
doubles are always the same size, which makes sum's running time O(1)×N = O(N).
int (formerly known as long) is arbitary-length. Let M denote the absolute value of the largest sequence element. Then sum's worst-case running time is lg(M) + lg(2M) + lg(3M) + ... + lg(NM) = N×lg(M) + lg(N!) = O(N log N).
For str (where M = the length of the longest string), the worst-case running time is M + 2M + 3M + ... + NM = M×(1 + 2 + ... + N) = O(N²).
Thus, summing strings would be much slower than summing numbers.
str.join does not allocate any intermediate objects. It preallocates a buffer large enough to hold the joined strings, and copies the string data. It runs in O(N) time, much faster than sum.
The Reason Why
#dan04 has an excellent explanation for the costs of using sum on large lists of strings.
The missing piece as to why str is not allowed for sum is that many, many people were trying to use sum for strings, and not many use sum for lists and tuples and other O(n**2) data structures. The trap is that sum works just fine for short lists of strings, but then gets put in production where the lists can be huge, and the performance slows to a crawl. This was such a common trap that the decision was made to ignore duck-typing in this instance, and not allow strings to be used with sum.
Edit: Moved the parts about immutability to history.
Basically, its a question of preallocation. When you use a statement such as
sum(["a", "b", "c", ..., ])
and expect it to work similar to a reduce statement, the code generated looks something like
v1 = "" + "a" # must allocate v1 and set its size to len("") + len("a")
v2 = v1 + "b" # must allocate v2 and set its size to len("a") + len("b")
...
res = v10000 + "$" # must allocate res and set its size to len(v9999) + len("$")
In each of these steps a new string is created, which for one might give some copying overhead as the strings are getting longer and longer. But that’s maybe not the point here. What’s more important, is that every new string on each line must be allocated to it’s specific size (which. I don’t know it it must allocate in every iteration of the reduce statement, there might be some obvious heuristics to use and Python might allocate a bit more here and there for reuse – but at several points the new string will be large enough that this won’t help anymore and Python must allocate again, which is rather expensive.
A dedicated method like join, however has the job to figure out the real size of the string before it starts and would therefore in theory only allocate once, at the beginning and then just fill that new string, which is much cheaper than the other solution.
I dont know why, but this works!
import operator
def sum_of_strings(list_of_strings):
return reduce(operator.add, list_of_strings)

Fortran CHARACTER FUNCTION without defined size [duplicate]

I am writing the following simple routine:
program scratch
character*4 :: word
word = 'hell'
print *, concat(word)
end program scratch
function concat(x)
character*(*) x
concat = x // 'plus stuff'
end function concat
The program should be taking the string 'hell' and concatenating to it the string 'plus stuff'. I would like the function to be able to take in any length string (I am planning to use the word 'heaven' as well) and concatenate to it the string 'plus stuff'.
Currently, when I run this on Visual Studio 2012 I get the following error:
Error 1 error #6303: The assignment operation or the binary
expression operation is invalid for the data types of the two
operands. D:\aboufira\Desktop\TEMP\Visual
Studio\test\logicalfunction\scratch.f90 9
This error is for the following line:
concat = x // 'plus stuff'
It is not apparent to me why the two operands are not compatible. I have set them both to be strings. Why will they not concatenate?
High Performance Mark's comment tells you about why the compiler complains: implicit typing.
The result of the function concat is implicitly typed because you haven't declared its type otherwise. Although x // 'plus stuff' is the correct way to concatenate character variables, you're attempting to assign that new character object to a (implictly) real function result.
Which leads to the question: "just how do I declare the function result to be a character?". Answer: much as you would any other character variable:
character(len=length) concat
[note that I use character(len=...) rather than character*.... I'll come on to exactly why later, but I'll also point out that the form character*4 is obsolete according to current Fortran, and may eventually be deleted entirely.]
The tricky part is: what is the length it should be declared as?
When declaring the length of a character function result which we don't know ahead of time there are two1 approaches:
an automatic character object;
a deferred length character object.
In the case of this function, we know that the length of the result is 10 longer than the input. We can declare
character(len=LEN(x)+10) concat
To do this we cannot use the form character*(LEN(x)+10).
In a more general case, deferred length:
character(len=:), allocatable :: concat ! Deferred length, will be defined on allocation
where later
concat = x//'plus stuff' ! Using automatic allocation on intrinsic assignment
Using these forms adds the requirement that the function concat has an explicit interface in the main program. You'll find much about that in other questions and resources. Providing an explicit interface will also remove the problem that, in the main program, concat also implicitly has a real result.
To stress:
program
implicit none
character(len=[something]) concat
print *, concat('hell')
end program
will not work for concat having result of the "length unknown at compile time" forms. Ideally the function will be an internal one, or one accessed from a module.
1 There is a third: assumed length function result. Anyone who wants to know about this could read this separate question. Everyone else should pretend this doesn't exist. Just like the writers of the Fortran standard.

Why doesn't .append() method work on strings, don't they behave like lists?

Why does this statement produce an error even though a string is actually a list of character constants?
string_name = ""
string_name.append("hello word")
The reason I expect this to work is because when we use for-loop, we are allowed to use this statement:
for i in string_name:
...
I think string_name is considered as a list here(?)
That's what they teach you in an algorithms and data structures class, that deal with algorithmic languages (unreal) rather than real programming languages, in Python, a string is a string, and a list is a list, they're different objects, you can "append" to a string using what is called string concatenation (which is basically an addition operation on strings):
string_name = "hello"
string_name = string_name + " world"
print(string_name) # => "hello world"
Or a shorthand concatenation:
string_name = "hello"
string_name += " world"
print(string_name) # => "hello world"
Lists and strings belong to this type called iterable. iterables are as they're name suggests, iterables, meaning you can iterate through them with the key word in, but that doesn't mean they're the same type of objects:
for i in '123': # valid, using a string
for i in [1, 2, 3]: # valid, using a list
for i in (1, 2, 3): # valid, using a tuple
for i in 1, 2, 3: # valid, using an implicit-tuple
# all valid, all different types
I strongly recommend that you read the Python Documentation and/or take the Python's Tutorial.
From Docs Glossary:
iterable
An object capable of returning its members one at a time. Examples of iterables include all sequence types (such as list, str, and tuple) and some non-sequence types like dict, file objects, and objects of any classes you define with an __iter__() or __getitem__() method. Iterables can be used in a for loop and in many other places where a sequence is needed (zip(), map(), …). When an iterable object is passed as an argument to the built-in function iter(), it returns an iterator for the object. This iterator is good for one pass over the set of values. When using iterables, it is usually not necessary to call iter() or deal with iterator objects yourself. The for statement does that automatically for you, creating a temporary unnamed variable to hold the iterator for the duration of the loop. See also iterator, sequence, and generator.
More about iterables.
Error is given when u try to append strings.So better first take list and then convert list to string.Code :
n='qwerty'
for i in range(1):
temp=[]
temp.append(n[-3:])
temp.append('t')
newtemp=' '
newtemp=temp[i]+temp[i+1]
print(newtemp)
Output:rtyt

Does the same String value always amount to the same String reference in AS3?

In AS3, do two Strings with the same value always have the same exact reference, without exception? In particular, I'm wondering if things like concatenated strings and strings returned from a web service can create duplicate instances of the same exact value.
For instance:
class Example
{
const MY_STRING:String = "Example";
.
.
.
private function myWebMethodResultHandler(pResult:ResultEvent):void
{
var myWebMethodString:String = pResult.result as String;
trace(myWebMethodString === MY_STRING); // returns true;
}
.
.
.
private function someOtherFunction():void
{
var str1:String = "Ex";
var str2:String = "ample";
var concatenatedString:String = str1 + str2;
trace(concatenatedString === MY_STRING); // returns true;
}
}
Is it absolutely guaranteed that in every case, including the ones above, that two Strings in AS3 with the same value are also the same exact instance with the same exact reference, or are there any cases at all in which Strings could be stored separately and as duplicate instances, taking up twice as much memory (and causing String comparisons to be more complicated internally than just comparing two 32-bit references)?
That is not correct, primitive types in AS3 are not compared by reference in strict equality but by value. The strict equality by reference is reserved to complex objects. 2 string with same value will never have the same reference (this is not Python).
Now AS3 is not the only language that treats primitive differently when it comes to strict comparison and because strict equality means same reference for complex object it is normal to assume the same is true for primitives but it's not. And yes constructing the same string 5 times will result in 5 different reference and 5 different object built but this is handled efficiently in AS3 like in other languages. As mentioned a language like Python does cache primitives and in that case 2 equal string or number are likely to point to the same reference but Python in that domain is more the exception than the rule.
So to resume a bit, strict equality in AS3 can be used to check strict equality between complex objects but when it comes to primitives it has no special meaning since it only compares values which is the same as simple equality.

Resources