Здесь есть несколько похожих запросов о функции IndexOf, но я обращаюсь, потому что, хотя предоставленные ответы были полезными, ни один из них не решил проблему.
У меня есть (очень) большой массив 2d из электронной таблицы имен и кодов id. Я прочитал эти значения в скрипте приложения в массив (rIdr
во фрагменте ниже).
Затем я создаю 2 одномерных массива, чтобы использовать IndexOf для поиска имени в первом массиве, а затем использовать возвращенный индекс для извлечения значения из второго массива.
var keys=[]; var vals=[];
//build key-val lookup arrays
for (var i = 0; i < rIdr.values.length; i++){
var k = rIdr.values[i][0].toString()
keys[i]=k
var v = rIdr.values[i][1].toString()
vals[i]=k
}
Имя, которое я ищу, получено из JSON, который заполняется в другом месте. Я перебираю имена в этом объекте, ища их в своих массивах key
и val
:
jsonobj.data.forEach(function(value) {
var idx = keys.indexOf(value.first_names_txt + " " + value.last_name_txt)
var id = -1;
if (idx > -1){id = vals[idx]}
Logger.log(value.first_names_txt + " " + value.last_name_txt + " " + id)
});
Я убедился, что как имя, которое я извлекаю из объекта JSON, так и элементы массива ключей являются типами String. Я видел в инспекторе объектов, что массив ключей представляет собой массив строк (а не, например, массив объектов-массивов).
Как бы я ни старался, я не могу заставить IndexOf вернуть что-либо, кроме -1. Даже если я явно ищу имя, которое, как я знаю, там есть (и на самом деле это копия и вставка имени, написанного на листе, из которого я извлекаю значения), я все равно получаю -1 возвращается
var test
test = keys.indexOf("Joe Bloggs")
Я рву на себе волосы. Я не хочу писать отдельную функцию для сопоставления имени в массиве ключей, потому что мне нужно либо передать полный массив keys
в качестве аргумента, либо сделать его глобальной переменной — ни то, ни другое я не хочу делать. по разным причинам.
Может ли кто-нибудь помочь, почему IndexOf здесь не работает?
И если это проблема, которая не исчезнет, есть ли способ написать мою собственную функцию поиска, которая позволяет избежать передачи больших массивов или объявления их глобальными переменными?
Спасибо всем заранее
Электронная таблица представляет собой просто список из 2 столбцов. Имя в первом столбце, идентификационный код во втором: <br> Jai Hindley 191310 <br> Richard Carapaz 3149
Можете ли вы показать, как устроен объект rIdr
? Я бы как-то Logger.log(rIdr.values[i][0]), возможно, это не то, что вы думаете.
извините, форматирование комментариев не сработало. Другое дело, что я создаю имя из объекта JSON, в котором хранятся имя и фамилия. Но, как я уже сказал, я даже не могу получить совпадение даже при использовании IndexOf с явным значением (например, Joe Bloggs выше)
@TheWizEd конечно var rIdr = Sheets.Spreadsheets.Values.get(SPREADSHEET_ID,"BCRiderList!A:C");
@TheWizEd также подтвердил, что массивы keys
и vals
заполняются так, как должны быть, и что тип данных в массиве keys
— String.
Так же, как примечание, не должно ли второе vals[i]=k
быть vals[i]=v
?
@TheWizEd да хорошее место! Это сэкономит мне время позже. На самом деле я использовал vals.push(v)
и keys.push(k)
, но изменил это обозначение, чтобы посмотреть, есть ли разница. К сожалению, нет.
Можете ли вы показать некоторые из ваших jsonobj?
Примером объекта является здесь, но, как я уже сказал, у меня возникают трудности с сопоставлением даже с IndexOf("Joe Bloggs"), поэтому я не думаю, что объект JSON является проблемой.
Есть ли какие-либо изменения дополнительных пробелов или необычных символов в значениях электронной таблицы. Потому что я не могу найти ничего плохого.
Нет - я даже использовал функцию .trim()
при заполнении массива keys
, но результат тот же.
Обеспечьте console.info(JSON.stringify(keys))
показ Joe Bloggs
Описание
Я создал электронную таблицу, используя имена из файла данных json, рандомизировал имена, чтобы они больше не располагались в алфавитном порядке, а затем присвоил каждому идентификатор.
В предоставленном мной образце сценария перечислены идентификационные номера имен в файле данных json. Обратите внимание, что я работаю с исходным массивом данных. Мне не нужно создавать массивы ключевых значений, чтобы получить желаемый результат. И я не проверяю, не существует ли имя в массиве данных.
Я обрезал данные json для краткости.
Код.gs
function test_json() {
try {
let jdata = {
"type" : "entrants",
"data" : [ {
"type" : "entrant",
"id" : "en_tdgwjajthr",
"first_names_txt" : "Archie",
"last_name_txt" : "White",
"entrytype" : "et_dv8u152j",
"answers" : {
"q_wg5qq6bgvsy90rh" : "Partenza Nude-Espresso RT"
}
}, {
.
.
.
.
}, {
"type" : "entrant",
"id" : "en_8uhauoe3jo",
"first_names_txt" : "Valentijn",
"last_name_txt" : "Brax",
"entrytype" : "et_dv8u152j",
"answers" : {
"q_wg5qq6bgvsy90rh" : "Dulwich Paragon CC"
}
} ],
"has_more_bool" : false
};
let values = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Test").getDataRange().getValues();
jdata.data.forEach(function(value){
let key = value.first_names_txt+" "+value.last_name_txt;
let found = values.find( row => row[0] === key );
console.info("key = "+key+" id = "+found[1]);
});
}
catch(err) {
console.info(err)
}
}
Журнал выполнения (сокращенно)
10:29:05 AM Notice Execution started
10:29:06 AM Info key = Archie White id = 21
10:29:06 AM Info key = ari panzer id = 15
10:29:06 AM Info key = Daniel Mulcahy id = 5
10:29:06 AM Info key = David Streule id = 12
10:29:06 AM Info key = Dominic Bell id = 10
10:29:06 AM Info key = Euan Davies id = 14
Спасибо @TheWized - это выглядит очень интересно. Я попробую вышеизложенное и отчитаюсь. Спасибо еще раз!
Привет, я получаю следующую ошибку 7:12:59 AM Error TypeError: values.find is not a function
мне не хватает библиотеки? это странно.
Игнорировать - эта часть работает. Теперь мне не удается найти совпадения, хотя я знаю, что ищу существующие элементы. Пробовал ToUpper()
но все равно не повезло. Мне интересно, хранятся ли данные, хранящиеся на листе, со скрытыми символами или таким образом, что это затрудняет сопоставление с использованием ===
или ==
. Это может объяснить проблему с самого начала (например, IndexOf
возвращает -1). В исходной электронной таблице я взял элемент данных и узнал его длину (используя =len(A12)
, и это, как и ожидалось, поэтому нет начальных/конечных пробелов.
Код, используемый для заполнения листа, находится в другом месте проекта: function updateBC_riderlookup() { var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("BCRiderList"); ss.clear(); var out=[]; for (var i = 0; i < BC_CATID_MAP.length; i++) { out=out.concat(fetchBC_RiderIDmap(BC_CATID_MAP[i][1],BC_CATID_MAP[i][0] )) } ss.getRange(ss.getLastRow() + 1, 1 , out.length, out[0].length).setValues(out); }
Единственный способ для меня увидеть, что представляют собой значения электронной таблицы, — это показать мне эту таблицу.
Можете ли вы опубликовать образец каждого из ваших источников данных?