I have a 2 dimensional array like this:
Name ID Date
0 Jhon 2 3
1 Elton 5 6
2 Gonza 8 9
3 Elton 6 1
(lets call PrincipalArray this data)
I have this array in a Google Sheet. I get this values to a 2 dimensional array in JavaScript in Google Apps Script.
Then i want to filter something like: "Number of row who have the name Elton and the ID is 6" --> output is "row 3"
I need this because i need to edit this row when the criteria is true and i need to know the number of row. And if does not exist something with this criteria i need an answer like "-1.00" when indexof can not find something.
I will repeat this search many times, i mean, i need this automated.
I was thinking in something similar like IndexOf but i can just IndexOf first column for Elton and does not exists and "indexOf with two criteria".
In pseudo-code i think this too:
- Get first column with names (new 1 dimension array "NamesArray")
- Get 2th column with IDs (new 1 dimension array "IDsArray")
- Filter Array to know how much Eltons are in the array (length of my For Loop)
- Loop for with "how much eltons are in array" as length
- Make indexof in First Column for "elton" ( NamesArray.indexOf("Elton")
- Use the result of Indexof in Elton to verify if the 2th column have that ID in that row
- iterate..
function asdasdasd() {
//My data in google sheets
var PrincipalArray = [ [ "Name", "IDs", "Date"],
[ "Jhon", 2, 3 ],
["Elton", 5, 6 ],
["Gonza", 8, 9 ],
["Elton", 6, 1 ],
];
//My first criteria to search
var NameToSearch = "Elton"; //will be an input variable by human
var IDsToSearch = "6"; //will be an input variable by human
//Name Get columns from 2 dimentional array because IndexOf only works in 1 dimentional array
var getColumns = (arr, indices) => arr.map(row => indices.map(i => row[i]));
var PrincipalArray_Col_Name_2darr = getColumns(PrincipalArray, [0]);
var PrincipalArray_Col_Name = PrincipalArray_Col_Name_2darr.map(
function(r) {return r[0];});
//IDs Get columns from 2 dimentional array because IndexOf only works in 1 dimentional array
var getColumns = (arr, indices) => arr.map(row => indices.map(i => row[i]));
var PrincipalArray_Col_IDs_2darr = getColumns(PrincipalArray, [1]);
var PrincipalArray_Col_IDs = PrincipalArray_Col_IDs_2darr.map(
function(r) {return r[0];});
//Filter the principal array then i can notice how much "Elton" there are
var PrincipalArray_OnlyName = PrincipalArray.filter(function(item){ return (item[0] == NameToSearch); } ); //output expected is 2 rows with Elton Data
//i will start the loop in the faster position
var positionNow = PrincipalArray_Col_Name.indexOf(NameToSearch); //output expected is 2, the first appear of Elton
//I will loop across the PrincipalArray but i will use IndexOf to go faster
for ( var i=positionNow ; i<PrincipalArray_OnlyName.length ; i ) {
//if is equal to "6" the ID of Elton
if ( PrincipalArray_Col_IDs[positionNow] == IDsToSearch ){
//i will edit that ID and run something here becuase is a match
Logger.log(PrincipalArray_Col_IDs[positionNow]);
break; //break because i found the ID with Elton, i edited that and is enough no more things to do and i want go outside of the loop for
}
var positionNow = PrincipalArray_Col_Name.indexOf(NameToSearch,positionNow); //output expected is 4 now becuase i am making an indexof starting in the previous step and i will find the next match of "elton"
if ( positionNow == PrincipalArray_OnlyName.length ) {
//here i will edit something becuase the ID was not found and i need to know that.
}
}
}
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
Use .findIndex()
:
/*<ignore>*/console.config({maximize:true,timeStamps:false,autoScroll:false});/*</ignore>*/
const principalArray = [ [ "Name", "IDs", "Date"],
[ "Jhon", 2 , 3 ],
["Elton", 5 , 6 ],
["Gonza", 8 , 9 ],
["Elton", 6, 1 ]
];
const find = (sKey,sID) => principalArray.findIndex(row => row[0]===sKey && row[1] === sID)
console.log(find('Elton', 6))
console.log(find('Elton',10))
console.log(find('Gonza',8))
<!-- https://meta.stackoverflow.com/a/375985/ --> <script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Or as a simple loop:
/*<ignore>*/console.config({maximize:true,timeStamps:false,autoScroll:false});/*</ignore>*/
const principalArray = [
['Name', 'IDs', 'Date'],
['Jhon', 2, 3],
['Elton', 5, 6],
['Gonza', 8, 9],
['Elton', 6, 1],
];
const find = (sKey, sID) => {
for (
let i = 0, row = principalArray[i];
i < principalArray.length;
row = principalArray[ i]
) {
if (row[0] === sKey && row[1] === sID) return i;
}
return -1;
};
console.log(find('Elton', 6));
console.log(find('Elton', 10));
console.log(find('Gonza', 8));
<!-- https://meta.stackoverflow.com/a/375985/ --> <script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
Use findIndex()
//My data in google sheets
var PrincipalArray = [ [ "Name", "IDs", "Date"],
[ "Jhon", 2 , 3 ],
["Elton", 5 , 6 ],
["Gonza", 8 , 9 ],
["Elton", 6, 1 ]
];
//My first criteria to search
var NameToSearch = "Elton"; //will be an input variable by human
var IDsToSearch = "6"; //will be an input variable by human
const target_row = PrincipalArray.findIndex(row => row[0] == NameToSearch && row[1] == IDsToSearch) 1;
console.log(target_row);
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>