Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #25093 > unrolled thread
| Started by | SteveYoungTbird <stephen.young@chello.at> |
|---|---|
| First post | 2014-06-27 09:17 +0200 |
| Last post | 2014-06-27 19:31 +0700 |
| Articles | 12 — 4 participants |
Back to article view | Back to comp.lang.javascript
Cannot manipulate array produced with string.match SteveYoungTbird <stephen.young@chello.at> - 2014-06-27 09:17 +0200
Re: Cannot manipulate array produced with string.match Denis McMahon <denismfmcmahon@gmail.com> - 2014-06-27 10:02 +0000
Re: Cannot manipulate array produced with string.match SteveYoungTbird <stephen.young@chello.at> - 2014-06-27 20:00 +0200
Re: Cannot manipulate array produced with string.match Denis McMahon <denismfmcmahon@gmail.com> - 2014-06-27 19:13 +0000
Re: Cannot manipulate array produced with string.match SteveYoungTbird <stephen.young@chello.at> - 2014-06-27 22:18 +0200
Re: Cannot manipulate array produced with string.match SteveYoungTbird <stephen.young@chello.at> - 2014-06-27 23:24 +0200
Re: Cannot manipulate array produced with string.match Denis McMahon <denismfmcmahon@gmail.com> - 2014-06-28 01:07 +0000
Re: Cannot manipulate array produced with string.match Denis McMahon <denismfmcmahon@gmail.com> - 2014-06-28 01:16 +0000
Re: Cannot manipulate array produced with string.match Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-06-28 23:53 +0200
Re: Cannot manipulate array produced with string.match SteveYoungTbird <stephen.young@chello.at> - 2014-06-29 22:24 +0200
Re: Cannot manipulate array produced with string.match Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-06-29 23:19 +0200
Re: Cannot manipulate array produced with string.match JJ <jj4public@vfemail.net> - 2014-06-27 19:31 +0700
| From | SteveYoungTbird <stephen.young@chello.at> |
|---|---|
| Date | 2014-06-27 09:17 +0200 |
| Subject | Cannot manipulate array produced with string.match |
| Message-ID | <loj5qn$cof$1@dont-email.me> |
I have produced an array using:
var arr = [];
arr = string.match(/(?:^| )([a-zäöüß]+)(?= [A-Z])/g);
This works as expected and the array is full and can be seen using
console.log or alert().
The array consists of words which I need to filter, so I am trying to
use .splice to remove unwanted instances of the same word using:
for (var i = arr.length - 1; i >= 0; i--) {
if (arr[i] === 'jim') {
arr.splice(i, 1);
}
}
The for loop doesn't recognize any instances of, for instance, 'jim' in
the array although there are several.
I tried the loop using an array I made myself and it worked fine, ie:
arr = ['jim', 'bob', 'arthur', 'jim', 'fred']
What is it about the array produced by the string.match that I am not
understanding? Any help would be much appreciated.
[toc] | [next] | [standalone]
| From | Denis McMahon <denismfmcmahon@gmail.com> |
|---|---|
| Date | 2014-06-27 10:02 +0000 |
| Message-ID | <lojfg6$i56$2@dont-email.me> |
| In reply to | #25093 |
On Fri, 27 Jun 2014 09:17:43 +0200, SteveYoungTbird wrote:
> I have produced an array using:
>
> var arr = [];
> arr = string.match(/(?:^| )([a-zäöüß]+)(?= [A-Z])/g);
>
> This works as expected and the array is full and can be seen using
> console.log or alert().
>
> The array consists of words which I need to filter, so I am trying to
> use .splice to remove unwanted instances of the same word using:
>
> for (var i = arr.length - 1; i >= 0; i--) {
> if (arr[i] === 'jim') {
> arr.splice(i, 1);
> }
> }
>
> The for loop doesn't recognize any instances of, for instance, 'jim' in
> the array although there are several.
>
> I tried the loop using an array I made myself and it worked fine, ie:
>
> arr = ['jim', 'bob', 'arthur', 'jim', 'fred']
>
> What is it about the array produced by the string.match that I am not
> understanding? Any help would be much appreciated.
Try using the following:
var i = arr.length;
while ( i-- )
if (arr[i] === 'jim')
arr.splice(i, 1);
else
console.log( "'" + arr[i].toString() + "' !== 'jim'" );
See what console.log is showing for words that don't match jim which you
expected to match jim.
--
Denis McMahon, denismfmcmahon@gmail.com
[toc] | [prev] | [next] | [standalone]
| From | SteveYoungTbird <stephen.young@chello.at> |
|---|---|
| Date | 2014-06-27 20:00 +0200 |
| Message-ID | <lokbfi$vac$1@dont-email.me> |
| In reply to | #25097 |
On 06/27/2014 12:02 PM, Denis McMahon wrote:
> On Fri, 27 Jun 2014 09:17:43 +0200, SteveYoungTbird wrote:
>
>> I have produced an array using:
>>
>> var arr = [];
>> arr = string.match(/(?:^| )([a-zäöüß]+)(?= [A-Z])/g);
>>
>> This works as expected and the array is full and can be seen using
>> console.log or alert().
>>
>> The array consists of words which I need to filter, so I am trying to
>> use .splice to remove unwanted instances of the same word using:
>>
>> for (var i = arr.length - 1; i >= 0; i--) {
>> if (arr[i] === 'jim') {
>> arr.splice(i, 1);
>> }
>> }
>>
>> The for loop doesn't recognize any instances of, for instance, 'jim' in
>> the array although there are several.
>>
>> I tried the loop using an array I made myself and it worked fine, ie:
>>
>> arr = ['jim', 'bob', 'arthur', 'jim', 'fred']
>>
>> What is it about the array produced by the string.match that I am not
>> understanding? Any help would be much appreciated.
>
> Try using the following:
>
> var i = arr.length;
> while ( i-- )
> if (arr[i] === 'jim')
> arr.splice(i, 1);
> else
> console.log( "'" + arr[i].toString() + "' !== 'jim'" );
>
> See what console.log is showing for words that don't match jim which you
> expected to match jim.
>
I did as you suggested and strangely the alert reads " 'jim' !== 'jim'
" as well as all of the other names not being equal to 'jim'
However if I use the array :-
arr = ['jim', 'bob', 'arthur', 'jim', 'fred']
the jim's are removed.
[toc] | [prev] | [next] | [standalone]
| From | Denis McMahon <denismfmcmahon@gmail.com> |
|---|---|
| Date | 2014-06-27 19:13 +0000 |
| Message-ID | <lokfoe$q6k$1@dont-email.me> |
| In reply to | #25103 |
On Fri, 27 Jun 2014 20:00:18 +0200, SteveYoungTbird wrote: > I did as you suggested and strangely the alert reads " 'jim' !== 'jim' > " as well as all of the other names not being equal to 'jim' Hmm, now you need to figure out what the differences are. I noticed that your original post had characters outside of the basic 7 bit ascii character set. Is it possible that you are comparing characters in different encodings? For example if 'jim' contains any of these characters, and 'jim' in your program code is in utf-8, but 'jim' in your string is in some other character set, then the representations of the non ascii characters might be different even though they look the same. -- Denis McMahon, denismfmcmahon@gmail.com
[toc] | [prev] | [next] | [standalone]
| From | SteveYoungTbird <stephen.young@chello.at> |
|---|---|
| Date | 2014-06-27 22:18 +0200 |
| Message-ID | <lokjjc$o0v$1@dont-email.me> |
| In reply to | #25104 |
On 06/27/2014 09:13 PM, Denis McMahon wrote: > On Fri, 27 Jun 2014 20:00:18 +0200, SteveYoungTbird wrote: > >> I did as you suggested and strangely the alert reads " 'jim' !== 'jim' >> " as well as all of the other names not being equal to 'jim' > > Hmm, now you need to figure out what the differences are. > > I noticed that your original post had characters outside of the basic 7 > bit ascii character set. Is it possible that you are comparing characters > in different encodings? > > For example if 'jim' contains any of these characters, and 'jim' in your > program code is in utf-8, but 'jim' in your string is in some other > character set, then the representations of the non ascii characters might > be different even though they look the same. > Ah, that sounds like a likely reason. The text that I am using .match on is read from a German RSS feed. Is there any way of converting it to utf-8 in javaScript if it is not already so encoded?
[toc] | [prev] | [next] | [standalone]
| From | SteveYoungTbird <stephen.young@chello.at> |
|---|---|
| Date | 2014-06-27 23:24 +0200 |
| Message-ID | <loknef$inh$1@dont-email.me> |
| In reply to | #25105 |
On 06/27/2014 10:18 PM, SteveYoungTbird wrote: > On 06/27/2014 09:13 PM, Denis McMahon wrote: >> On Fri, 27 Jun 2014 20:00:18 +0200, SteveYoungTbird wrote: >> >>> I did as you suggested and strangely the alert reads " 'jim' !== 'jim' >>> " as well as all of the other names not being equal to 'jim' >> >> Hmm, now you need to figure out what the differences are. >> Got it! arr.match produces a string with a space after the comma. Therefore 'jim' in the loop was actually ' jim' and therefore didn't match, Thanks for your help.
[toc] | [prev] | [next] | [standalone]
| From | Denis McMahon <denismfmcmahon@gmail.com> |
|---|---|
| Date | 2014-06-28 01:07 +0000 |
| Message-ID | <lol4g3$or3$1@dont-email.me> |
| In reply to | #25106 |
On Fri, 27 Jun 2014 23:24:31 +0200, SteveYoungTbird wrote:
> Got it! arr.match produces a string with a space after the comma.
> Therefore 'jim' in the loop was actually ' jim' and therefore didn't
> match,
Observation: You had all the information you needed to solve this, you
just needed to figure out how to view that information. :)
If you wanted a really deep dissection of the compares to the console you
could use something like the following, which prints length, character
and character code mismatches:
var arr = ["fred","jim","pete"," jim","andrew"," jim ","bert",
"jim ","henry","jim","mike"];
var i = arr.length, j, k;
console.log( arr.toString() );
while ( i-- ) {
if (arr[i] === 'jim') {
arr.splice(i, 1);
}
else {
console.log( "'" + arr[i].toString() + "' !== 'jim'" );
if ( arr[i].toString().length != "jim".length ) {
console.log( "'" + arr[i].toString() + "'.length = " +
arr[i].toString().length +
" != 'jim'.length = " + "jim".length );
}
k = arr[i].toString().length > "jim".length ?
arr[i].toString().length :
"jim".length;
for ( j = 0; j < k; j++ ) {
if ( arr[i].toString().charAt(j) !== "jim".charAt(j) ) {
console.log( "arr[i].toString().charAt(j) [" +
arr[i].toString().charAt(j) +
"] !== 'jim'.charAt(j) [" +
"jim".charAt(j) + "]" );
}
if ( arr[i].toString().charCodeAt(j) !==
"jim".charCodeAt(j) ) {
console.log( "arr[i].toString().charCodeAt(j) [" +
arr[i].toString().charCodeAt(j) +
"] !== 'jim'.charCodeAt(j) [" +
"jim".charCodeAt(j) + "]" );
}
}
}
}
console.log( arr.toString() );
--
Denis McMahon, denismfmcmahon@gmail.com
[toc] | [prev] | [next] | [standalone]
| From | Denis McMahon <denismfmcmahon@gmail.com> |
|---|---|
| Date | 2014-06-28 01:16 +0000 |
| Message-ID | <lol51s$or3$2@dont-email.me> |
| In reply to | #25107 |
On Sat, 28 Jun 2014 01:07:15 +0000, Denis McMahon wrote:
> [code]
Better solution:
var arr = ["fred","jim","pete"," jim","andrew"," jim ","bert",
"jim ","henry","jim","mike"];
var i = arr.length, j, k;
console.log( arr.toString() );
while ( i-- ) {
if (arr[i] === 'jim') {
arr.splice(i, 1);
}
else {
console.log( "'" + arr[i].toString() + "' !== 'jim'" );
if ( arr[i].toString().length != "jim".length ) {
console.log( "'" + arr[i].toString() + "'.length [" +
arr[i].toString().length +
"] != 'jim'.length [" + "jim".length + "]" );
}
k = arr[i].toString().length > "jim".length ?
arr[i].toString().length :
"jim".length;
for ( j = 0; j < k; j++ ) {
if ( arr[i].toString().charAt(j) !== "jim".charAt(j) ) {
console.log( "arr[i].toString().charAt(" + j + ") [" +
arr[i].toString().charAt(j) +
"] !== 'jim'.charAt(" + j + ") [" +
"jim".charAt(j) + "]" );
}
if ( arr[i].toString().charCodeAt(j) !==
"jim".charCodeAt(j) ) {
console.log( "arr[i].toString().charCodeAt(" + j +
") [" + arr[i].toString().charCodeAt(j) +
"] !== 'jim'.charCodeAt(" + j + ") [" +
"jim".charCodeAt(j) + "]" );
}
}
}
}
console.log( arr.toString() );
--
Denis McMahon, denismfmcmahon@gmail.com
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2014-06-28 23:53 +0200 |
| Message-ID | <1892446.4VnW0yGc5p@PointedEars.de> |
| In reply to | #25106 |
SteveYoungTbird wrote:
> On 06/27/2014 10:18 PM, SteveYoungTbird wrote:
>> On 06/27/2014 09:13 PM, Denis McMahon wrote:
>>> On Fri, 27 Jun 2014 20:00:18 +0200, SteveYoungTbird wrote:
>>>> I did as you suggested and strangely the alert reads " 'jim' !== 'jim'
>>>> " as well as all of the other names not being equal to 'jim'
>>> Hmm, now you need to figure out what the differences are.
>
> Got it! arr.match produces a string with a space after the comma.
s/arr/string/
> Therefore 'jim' in the loop was actually ' jim' and therefore didn't
> match,
It produces that because you have /(?:^| )/ in
>>>>>> var arr = [];
^^^^^[1][2]
>>>>>> arr = string.match(/(?:^| )([a-zäöüß]+)(?= [A-Z])/g);
[3]^^^^^^^^[4]-------^^^^^^^^^^^[5]
The /(?:…)/ only prevents capturing; it is _not_ a zero-length lookbehind
(/(?<!…)/ would be, but it is not supported in ECMAScript as yet).
Many parts of this code do not make sense:
[1] These languages use dynamic type-checking. You do not need to
initialize a variable that you will assign a reference to an Array
instance with a reference to an Array instance.
[2] No additional initialization is necessary. String.prototype.match()
always returns a reference to an Array instance if successful
(otherwise “null” which overwrites the previous value anyway).
[3] /(?:^| )…/g does not make sense, see above.
[4] Capturing the sequence of word characters does not make sense with
the global flag, as the resulting Array only contains the matches
as primitive string values, if any.
[5] /…(?= [A-Z])/g (zero-length positive lookahead) does not appear to
make sense when you want to match/filter words. Why would you only
match words that precede a word starting with a capital letter?
What about multiple spaces, tabs, and newlines?
In order to match words, simply match consecutive word characters (for the
non-word characters delimit words and are not matched):
var arr = string.match(/[a-zäöüß]+/ig);
JSX:regexp.js can help there with basic support for Unicode character
properties, like \p{L} for all letters. But if you want to use .match()
instead of .exec() then, you need to cast the String to a jsx.regexp.String:
/*
* ["Über", "sprießende", "Äcker", "liefen", "zwölf", "Hühner",
* "sagte", "der", "Bär", "in", "der", "Öffentlichkeit"]
*/
new jsx.regexp.String(
"Über sprießende Äcker liefen zwölf Hühner, sagte der Bär"
+ " in der Öffentlichkeit."
).match(new jsx.regexp.RegExp("\\p{L}+", "g"))
(You could say that this sentence – that just came to my mind – is an umlaut
pangram, as a proof-of-concept. It also features the sz ligature, used as
in non-reformed Federal German spelling.)
See also:
- <http://PointedEars.de/scripts/test/regexp>
- <http://stackoverflow.com/a/8568325/855543>
- My sig for the source code.
In order to filter out words, simply match on them or replace them. There
is no need for array iteration.
That said, Array.prototype.filter() (ES 5+) and equivalents are more
efficient here than multiple Array.prototype.splice(), even though you
cleverly iterate in reverse order so that the changed length does not
matter.
Please post using your real name.
--
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not Cc: me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | SteveYoungTbird <stephen.young@chello.at> |
|---|---|
| Date | 2014-06-29 22:24 +0200 |
| Message-ID | <lopsmb$uvo$1@dont-email.me> |
| In reply to | #25110 |
On 06/28/2014 11:53 PM, Thomas 'PointedEars' Lahn wrote: > > [5] /…(?= [A-Z])/g (zero-length positive lookahead) does not appear to > make sense when you want to match/filter words. Why would you only > match words that precede a word starting with a capital letter? > What about multiple spaces, tabs, and newlines? I am trying to identify German adjectives in a text. I thought that if I made an array of all the words that appeared before a noun (always capitalized in German) and then removed definite and indefinite articles, personal pronouns and other common words such as "von" etc I could then check the remaining words against an array of German adjectives. I would be grateful if someone could show me a better way. > > In order to filter out words, simply match on them or replace them. There > is no need for array iteration. I have explained why I think there is a need for array iteration above > Please post using your real name. Please don't think I'm being rude, but is your real name Thomas 'PointedEars' Lahn? Steve Young (from my Thunderbird newsreader)
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2014-06-29 23:19 +0200 |
| Message-ID | <2459586.3RATVSoWxJ@PointedEars.de> |
| In reply to | #25123 |
SteveYoungTbird wrote: > On 06/28/2014 11:53 PM, Thomas 'PointedEars' Lahn wrote: >> [5] /…(?= [A-Z])/g (zero-length positive lookahead) does not appear to >> make sense when you want to match/filter words. Why would you only >> match words that precede a word starting with a capital letter? >> What about multiple spaces, tabs, and newlines? > > I am trying to identify German adjectives in a text. I thought that if I > made an array of all the words that appeared before a noun (always > capitalized in German) and then removed definite and indefinite > articles, personal pronouns and other common words such as "von" etc I > could then check the remaining words against an array of German > adjectives. I would be grateful if someone could show me a better way. Neither are all words adjectives that precede a capitalized word (e.g „Morgen geht es /ums/ Ganze.“ [approx. “It’ll be do or die tomorrow.”]); nor, because of variable word order, do all adjectives precede a noun in German (e.g. „Das Spiel heute war /spannend/.“ vs. “Heute war ein spannendes Spiel.” [“Today’s match was exciting.”/“It/there was an exciting match today.”]). It is also insufficient to match only lowercase words because, although adjectives are usually written lowercase in German, too, proper names can contain capitalized adjectives (e.g. „Der /Fliegende/ Holländer“ [“The Flying Dutchman”], „Der /Elektrische/ Reporter“ [approx.: “The Electric Reporter”]), and nominalizations are common in German (often poetic or in an [recently, often misguided] attempt to avoid [seemingly] gender-specific forms, e.g. „der /Schlafende/“ [“the sleeper”], „die Studierenden“ [“the (university) students”]). Syntax analysis is far more complex that you think, particularly that of German. You appear to have an XY problem. >> Please post using your real name. > > Please don't think I'm being rude, but is your real name Thomas > 'PointedEars' Lahn? My real name is Thomas Lahn. It is customary, at least on the Net, to insert the nickname in the real name like I do. -- PointedEars FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/> Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix> Please do not Cc: me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | JJ <jj4public@vfemail.net> |
|---|---|
| Date | 2014-06-27 19:31 +0700 |
| Message-ID | <uzip81820by1$.1s9nakgot7koy.dlg@40tude.net> |
| In reply to | #25093 |
On Fri, 27 Jun 2014 09:17:43 +0200, SteveYoungTbird wrote:
> I have produced an array using:
>
> var arr = [];
> arr = string.match(/(?:^| )([a-zäöüß]+)(?= [A-Z])/g);
>
> This works as expected and the array is full and can be seen using
> console.log or alert().
>
> The array consists of words which I need to filter, so I am trying to
> use .splice to remove unwanted instances of the same word using:
>
> for (var i = arr.length - 1; i >= 0; i--) {
> if (arr[i] === 'jim') {
> arr.splice(i, 1);
> }
> }
>
> The for loop doesn't recognize any instances of, for instance, 'jim' in
> the array although there are several.
>
> I tried the loop using an array I made myself and it worked fine, ie:
>
> arr = ['jim', 'bob', 'arthur', 'jim', 'fred']
>
> What is it about the array produced by the string.match that I am not
> understanding? Any help would be much appreciated.
It's just a normal array.
Are you sure the for loop actually succeeded? Cause if nothing matched, arr
would be null and arr.length would generate an error. And I don't see any
error handling.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.javascript
csiph-web