Reputation: 488
So I have a function that takes in a two-dimensional array and a string. It then searches through the table and counts how many times the given string is found.
Here is the code:
function getNumberShifts(table, name) {
var amount = 0;
for(i = 0; i < table.length; i++){
for(j = 0; j < table[i].length; j++){
var text = table[i][j].toString();
if(text.indexOf(name)>-1){
amount += 1;
}
}
}
return amount;
}
The 2D-array is not that big, about 30 x 60. Most of the cells are empty or contain 1 element (name). Sometimes it can contain two.
Is there a more efficient way than O(n^2)? (This is a Google Sheets Script)
Thanks in advance!
Edit: Example-table:
Time | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Monday | ...
12:00| --name1 | ---name2 | ----name3 | ---name2 | name4 | ----name1 | name2 | ...
.
.
.
(Ignore the dashes, they are only for formatting purposes so you guys "see" the table)
This is basically it. Just a table with names. The top row and the left coloumn are not a part of the table that is sent to the function. Just the names. Some of the cells are completeley empty, (So it's easier to read it for me and my coworkers)
Upvotes: 1
Views: 655
Reputation: 104780
It may be that converting the array to a string and using string's indexOf,
incrementing the index after each match, would be less laborious than
iterating through the array.
function getNumberShifts(table, name){
var i= 0, amount= 0, text= table.join(' ');
while((i= text.indexOf(name,i)+1)){
++amount;
}
return amount;
}
var A1= [
[0, "name2"], [1, ""], [2, "name2"], [3, ""],
[4, "name3"], [5, ""], [6, "name2"], [7, ""], [8, "name2"], [9, "name3"],
[10, "name2"], [11, ""], [12, "name2"], [13, ""], [14, "name3"], [15, ""],
[16, "name2"], [17, ""], [18, "name2"], [19, "name3"], [20, "name2"],
[21, ""], [22, "name2"], [23, ""], [24, "name3"], [25, ""],
[26, "name2"], [27, ""], [28, "name2"], [29, "name3"]
]
getNumberShifts(A1, 'name3');
/* returned value: (Number) 6 */
Upvotes: 0
Reputation: 44396
You cannot do it faster for one search. As Safari points out, you have to look in every cell once, there are n^2 cells, so...
But if you are searching multiple times, it may make sense to preprocess the 2D array into a single hash-array. So a n^2 set-up time but only a log(n) look-up time for each search.
var getNumberShiftsFinder = function(table) {
var found = {};
for(var i = 0; i < table.length; i++){
for(var j = 0; j < table[i].length; j++) {
var text = table[i][j].toString();
found[text] = 1 + ( found[text] || 0 );
}
}
return function(name) {
return found[name] || 0;
};
};
Upvotes: 0
Reputation: 3382
Sorry, but there is no faster way of doing that. You need to check every single cell at least once.
Upvotes: 2