简体   繁体   中英

How to attach the previous item to the next in array?

I want to add the previous value to each array item except the first one Use the following code,result is true.input is ['python','jieba'],output is [ 'python', 'python jieba' ]

var config={keywords: ['python','jieba']}
var keywords=config.keywords
for(keyword in keywords){

 if (keyword==0){

 }
 else{
    keywords[keyword]=keywords[keyword-1]+" "+keywords[keyword]
    console.log(keywords)
 }
}

But if I use an if statement,the code like this:

var config={keywords: ['python','jieba']}
var keywords=config.keywords
for(keyword in keywords){

 if (keyword!==0){

    keywords[keyword]=keywords[keyword-1]+" "+keywords[keyword]
    console.log(keywords)
 }

}

The return is wrong,

[ 'undefined python', 'jieba' ]
[ 'undefined python', 'undefined python jieba' ]

Is the if statement incorrectly written?

This sounds like a job for reduce :

 var keywords = ['python', 'jieba']; keywords.reduce((a, b, i) => keywords[i] = `${a} ${b}`); console.log(keywords); 

Of course, if you only want to get the final result (all the keywords combined together), just use join :

 var keywords = ['python', 'jieba']; var joinedKeywords = keywords.join(' '); console.log(joinedKeywords); 

The key is a string.

You need to take

if (keyword != 0) {

or better

if (keyword !== '0') {

 var config = { keywords: ['python', 'jieba'] }, keywords = config.keywords, keyword; for (keyword in keywords) { if (keyword !== '0') { keywords[keyword] = keywords[keyword - 1] + " " + keywords[keyword] console.log(keywords) } } 

You are comparing a String to a Number. change your condition to if (keyword!=='0') . And you are trying to access an index that does not exist when first calling keywords[keyword-1] .

Also, I do not recommend to use for...in in your case, but rather a simple for loop or more advanced solution using Array.reduce (see the answer by @pswg). I quote the MDN for...in entry:

Array indexes are just enumerable properties with integer names and are otherwise identical to general object properties. There is no guarantee that for...in will return the indexes in any particular order. The for...in loop statement will return all enumerable properties, including those with non–integer names and those that are inherited.

Because the order of iteration is implementation-dependent, iterating over an array may not visit elements in a consistent order. Therefore, it is better to use a for loop with a numeric index (or Array.prototype.forEach() or the for...of loop) when iterating over arrays where the order of access is important.

 var config = { keywords: ['python', 'jieba'] } var keywords = config.keywords for (var i = 1; i < keywords.length; i++) { // starting with i=0 would try to access keywords[0 - 1] which results in undefined if (keywords[i] != 0) { keywords[i] = keywords[i - 1] + " " + keywords[i] console.log(keywords) } } 

Consider switching to a traditional for loop using an index instead of for-in:

 var config = {keywords: ['python', 'jieba']}; var keywords = config.keywords; for (var i = 1; i < keywords.length; i++) { keywords[i] = keywords[i - 1] + " " + keywords[i]; console.log(keywords); } 

I think it's regrettable that you accepted Nina's answer because she skips an important point and this omission can be misleading. Consider reading this answer again, it was the most enlightening in my opinion: https://stackoverflow.com/a/54700039/1636522 . The quote from MDN tells us that iterating over an array with a for...in loop is a bad idea for two reasons. The first one is obvious with an example:

> | xs = ["a"]
< | ["a"]
> | for (i in xs) console.log(i, xs[i])
  | 0 a
> | xs["a"] = 0
< | 0
> | for (i in xs) console.log(i, xs[i])
  | 0 a
  | a 0

Sad, and this is not a bug :-\\ Indeed, for...in is meant to iterate over enumerable properties, and indexes are only a part of it.

> | Object.keys(xs) // returns enumerable properties
< | ["0", "a"]

The second reason is that for...in may not visit elements in consistent order. Most of the time everything works as expected, but someday you could observe a weird behaviour like this:

> | xs = ["a", "b"]
< | ["a", "b"]
> | for (i in xs) console.log(i, xs[i])
  | 1 b
  | 0 a

Again, this is not a bug. Since properties are not always indexes, there is no reason to visit them in a specific order. It could be harmful considering your requirements. Indeed, push one more element to the array and your algorithm is likely to have unpredictable behaviour:

> | xs = ["python", "jieba", "more"]
< | ["python", "jieba", "more"]
> | for (i in xs) {
  |   if (i !== "0") xs[i] = xs[i - 1] + " " + xs[i];
  |   console.log(i, xs[i]);
  | }
  | xs

The above code may produce the expected trace:

  | 0 python
  | 1 python jieba
  | 2 python jieba more
< | ["python", "python jieba", "python jieba more"]

But it may also produce something unexpected like this:

  | 2 jieba more
  | 0 python
  | 1 python jieba
< | ["python", "python jieba", "jieba more"]

Now I hope this is clear for you that using for...in to iterate over an array is a bad habit. You should better switch to either a good old for loop or a for...of loop:

> | for (i = 0; i < xs.length; i++) console.log(i, xs[i])
  | 0 "a"
> | for (x of xs) console.log(x)
  | a

Finally, let's get to the bottom of the question. Why keyword != 0 works while keyword !== 0 fails? Keep in mind that for...in is looking for object keys, and a key is a string. Now look:

> | "0" != 0 // normal equality with type conversion
< | false
> | "0" !== 0 // strict equality with type comparison
< | true

Got it? A key is not a number :-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM