iT邦幫忙

0

我是弱弱新手,想請教JS的indexOf問題...

大大們好,想請教一個問題,就是我用indexOf無法查找到,總是回傳-1:

var ctList = ws.getRange('A2:A60').getValues();
var position = ctList.indexOf(ctarget);
return position;

為了測試,把ctarget直接換成儲存格內的文字'ABC',還是回傳-1,這是甚麼原因呢?

想了很久都想不出來,但是寫成:var position = ctList.indexOf(ctList[0]);
則又可以正常回傳0。

我功力太弱,冒昧跟大大們請教,麻煩大大們指導了,感謝不盡!!

看更多先前的討論...收起先前的討論...
淺水員 iT邦高手 2 級 ‧ 2021-10-15 18:06:50 檢舉
先 console.log(ctList) 看看 ctList 存了什麼吧
iyar0810 iT邦新手 5 級 ‧ 2021-10-15 21:23:50 檢舉
大大好,我回傳了ctarget、ctList[0],是2個相同的拼字。
但ctList.indexOf(ctarget)卻是-1,真苦惱QQ。
console.log(ctList) 顯示[[ 'ABC' ], [ 'CDE' ],['EFG']]這樣,多了一層[]不知道是否有關係?!麻煩您幫我看一下,感謝!!
淺水員 iT邦高手 2 級 ‧ 2021-10-16 18:39:32 檢舉
這樣可以考慮用 findIndex
參考 https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex
kekeke iT邦新手 4 級 ‧ 2021-10-18 17:01:18 檢舉
不知這樣是否能幫你解決問題:
console.log(a.map((a)=>a.join()).indexOf('ABC'));
0
科技君 Shawn
iT邦新手 5 級 ‧ 2021-10-18 19:38:07
最佳解答

個人推測你應該是在開發 Google App Script ? 因為 getValues 會把每個儲存格的資料當作一個獨立 array,包含在一個大 array 裡,所以用 indexOf 會找不到,畢竟關鍵字是 string,但儲存格資料被包在 array 裏面。因此你 console.log(clist)會看到雙重 array。

你需要的是在這句後面加 .flat() :
var ctList = ws.getRange('A2:A60').getValues().flat()

這時候 console.log(ctList) 應該會是 ['ABC', 'CDE','EFG'],每個資料都會是獨立的 string 了,我剛實測是可以 indexOf 到的,供你參考。

0
bsexp301479
iT邦新手 4 級 ‧ 2021-10-15 17:06:54

以我用C#寫抓取Excel資料的經驗
有可能是儲存格內的文字格式問題
之前遇到的問題是抓取資料的時候儲存格內不能使用通用格式
必須固定為文字格式才能正常讀到資料
但不知道JS有沒有這個問題

提供給你參考

iyar0810 iT邦新手 5 級 ‧ 2021-10-15 17:25:35 檢舉

謝謝大大建議,剛才有試著去設定文字格式,還是回傳-1。
謝謝您抽空幫忙。

那還是你先console.log(ctList)確認一下資料列裡的值是否是正確的
如果值都是對的那就是position傳的參數有誤了

0
screenleon
iT邦新手 1 級 ‧ 2021-10-15 17:10:58

因為你沒宣告或指定ctarget
JS不會因為你沒宣告就顯示錯誤

iyar0810 iT邦新手 5 級 ‧ 2021-10-15 17:24:51 檢舉

大大好,在其他地方有定義:
var ctarget = document.getElementById("autoin").values;
google.script.run.withSuccessHandler(udAg).getAgent(ctarget);
還是說這樣定義會有問題? 有嘗試把ctarget換成'ABC'這樣的文字,也是回傳-1。

1
jason71708
iT邦新手 5 級 ‧ 2021-10-22 17:58:44

陣列.indexOf(目標) 是找尋該陣列內有符合目標並回傳該元素的 index (先找到就回傳,如果有兩三個元素都符合目標都只會回傳第一個符合的)

const beasts = ['ant', 'bison', 'camel', 'duck', 'bison'];
console.log(beasts.indexOf('bison'));
// expected output: 1

範例來源: MDN

你遇到的問題是 ctList 實際資料長這樣:陣列裡面又有陣列

var ctList = [[ 'ABC' ], [ 'CDE' ], [ 'EFG' ]]
// 陣列裡面又有陣列 (兩層陣列)

所以 ctList.indexOf(ctarget) 時就會變成這樣在比對

[ 'ABC' ] 是否等於 'ABC'
[ 'CDE' ] 是否等於 'ABC'
[ 'EFG' ] 是否等於 'ABC'
陣列 是否等於 字串

想當然回傳結果都會是 -1 (找不到)

解答 1: 所以你可以使用 科技君 Shawn 提供的方法:

var ctList = ws.getRange('A2:A60').getValues().flat()
// ctList = ['ABC', 'CDE', 'EFG']
var position = ctList.indexOf(ctarget);
return position;

將兩層陣列打平成一層後就可以依照你原本寫的程式邏輯輸出你要的 position = 0

解答 2: 也可以使用 for迴圈Array.reduce()Array.forEach() 等方法取得第二層陣列再一個個 indexOf(ctarget) ,找第二層陣列內有無符合的字串

var ctList = ws.getRange('A2:A60').getValues()
var positionList = []
for (var i = 0; i < ctList.length; i++) {
    var position = ctList[i].indexOf(ctarget)
    positionList.push(position)
}
console.log(positionList)
// expected output: [0, -1, -1] 代表第二層陣列中,第一個陣列內有你要的字串,其他陣列都沒找到

我要發表回答

立即登入回答