下列的函式
若把
for(var i in nums)
改成
for(var i = 0; i < nums.length; i++)
會無法傳回正確的值
想請問其間差異,謝謝
/**
* @param {number[]} nums
* @param {number} k
* @return {boolean}
*/
var containsNearbyDuplicate = function(nums, k) {
var map = {};
for(var i in nums) {
var v = nums[i];
if(map[v] && (i - map[v] <= k)) {
return true;
}
map[v] = i;
}
return false;
};
一般很多語言用的都是foreach,
意思是一樣的
for(var i = 0; i < nums.length; i++)
只能讀取連續的資料,而且不能遇到不存在的索引,否則會出錯。
foreach(var data in nums)
可以讀取不連續的資料,會將nums這個List裡面的所有資料都跑一遍,
不過foreach缺點是你不知道i是多少,
不過有些語言也有能夠讀取到key值的方式,
很多情況下是兩種方法都可以使用,
就看你的需求跟個人的習慣了。
我剛才又看了一次題目,
for(var i in nums)
裡面的i是nums這個List裡面的值
for(var i = 0; i < nums.length; i++)
是從0開始的數字,
如果你直接拿這個i下去使用,一定是會出錯的,
你試著改成
for(var i = 0; i < nums.length; i++){
var v = nums[nums[i]];
... ...
把裡面的i改成nums[i]試試看
謝謝你的回答
不過我主要的問題都是for迴圈
只是他主要是for連續跟for/in這2種
因為我有自己用這兩種方法跑過其他的
感覺大致上差異不大
但不知道為什麼這邊會造成差異
for/in應該是這樣吧0.0
for(變項 in 物件/陣列)
變項為物件屬性或陣列的索引
JavaScript的for/in我比較不熟,用C#來說明吧
假如有一個
List<int> list = new List<int> { 2, 3, 4, 5, 1 }
如果你是
for(int i=0;i<5;i++)
抓出來的i是0, 1, 2, 3, 4
但如果是
foreach(var i in list)
抓出來的i是 2, 3, 4, 5, 1
你會抓到結果不一樣可能是這個原因吧。
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Statements/for...in
https://stackoverflow.com/questions/500504/why-is-using-for-in-with-array-iteration-a-bad-idea
javascript 的陣列用 for in 存取和用 for 使用 index 存取的確不一樣,要注意。
for in 會跳過 array 中 undefined 的物件。
另外 array 還有個 foreach 方法。
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
上網查過之後建議會用for遞增比較安全
但這邊反而是要用for/in才會回正確的值
讓我感到困惑
所以想知道差異
以更了解使用時機
我上面寫的你有看懂嗎?
你把你的for遞增怎麼寫的PO出來,
跟for/in比較看看,
再來討論吧。
var nums = [1,3,3,1,4]
map = {};
for(var i in nums){
var v = nums[i];
map[v] = i;
}
"4"
map
{1: "3", 3: "2", 4: "4"}
for(var i = 0; i < nums.length; i++){
var v = nums[i];
map[v] = i;
}
4
map
{1: 3, 3: 2, 4: 4}
剛剛用console跑出的結果
關鍵差異應該就是
一個是取索引鍵
一個是取索引值
這樣我大概知道為什麼for遞增會錯了
謝謝大家的回應
...這應該是很基本的scence吧。
剛剛試了一下,
我誤會了,
我以為for/in 和 foreach是一樣的,
結果完全不一樣...
的確兩個i的值看起來一樣,
但不知為何一個有""一個沒有,
這你就要去找資料看看了...
他判斷map裡是否已經有該屬性
用if(map[v])
這個方法不夠嚴謹
這樣會變成是用map[v]的值去找屬性
所以沒有""會找不到
我覺得這邊算是碰巧有相同屬性
如果改成if(("" + v) in map)
這樣才是確實是找屬性
改成這樣用for遞增就不會回傳錯誤
也是比較正確的作法
當初糾結的點
其實就是在於他寫法不夠嚴謹又剛好會造成差異
上面我給你的連結有寫到。
for in 會跳過陣列裡值為 undefined 的 index,所以考慮到 num = [1,3, ,3]這種情形,可以很輕易的略過 num[2] 為 undefined 不能當鍵值的問題,你用 for(i, i < num.length, i++)去做,這種處理會麻煩很多。
另外還要注意的一點,for in 取出來的值會是 string,for(i, i < num.length, i++)取出來的i會是整數。
stackoverflow那篇為什麼會說最好還是用for(i, i < num.length, i++)去做整個陣列的存取,是因為這樣能確保陣列裡每一個index都能依順序去處理,for in只會去處理有賦值的陣列元素,而且for in的順序還會依 javascript 引擎實做不同而不同,甚至結果也不同,連用prototype都會傳回prototype程式碼內容的string,所以for in不好控制。但在你給的原code我不覺得有用錯的地方。
最後 "" + v 這種寫法不能說錯,不過就閱讀上來說很難看。
建議用string(v)。
謝謝