I am doing the first problem on LeetCode, Two Sum. I am trying to do the problem using a hash table. This is what I came up with:
var twoSum = function(nums, target) {
var hash = [];
for(var i = 0; i < nums.length; i++) {
var need = target - nums[i];
if (!hash[need]) {
hash[need] = i;
} else {
return [hash[nums[i]], i];
}
}
};
When I run my code, I am getting undefined as an answer. Let's say I have an array [2,3,1,6,4] and my target is 8. When I iterated through the array, I will get 8-2=6, 8-3=5, 8-1=7, 8-6=2, and 8-4=4. So, my hash table should look like this according to my code:
6:0
5:1
7:2
2:3
4:4
If something is not in the hash table, I want to throw it into the hash. When I run into the number in the hash, then I return hash[nums[i]] and i since I am ready at the index and hash[nums[i]] has the value of the index that I need. I am unsure why I am getting an undefined. Any advice to make this better?
Please see the code. I have removed the else part and returned the hash at end. Please let me know if this is what you were looking.
var twoSum = function(nums, target) {
var hash = [];
for(var i = 0; i < nums.length; i++) {
var need = target - nums[i];
if (!hash[need]) {
hash[need] = i;
}
}
return hash;
};
console.log(twoSum([2,3,1,6,4],8))
Related
I'm wanting to remove duplicate values from the array tabData produced by the script below.
I've found numerous posts here that mention "removing duplicates from array", but don't seem to be relevant to my exact goal.
I've tried filter, I've tried using this answer and adjusting the variables to fit my script, but it did not remove the duplicates.
Surely there is a simple function that does exactly what I'm looking for, I'm just not finding it.
function getTabArray() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var version = ss.getRangeByName("version").getValue().toString();
var updateTabsName = "updateTabs";
var updateTabsSheet = ss.getSheetByName(updateTabsName);
var tabDataRows = updateTabsSheet.getLastRow();
var tabDataCols = updateTabsSheet.getMaxColumns() - 1;
var tabDataRange = updateTabsSheet.getRange(1, 2, tabDataRows, tabDataCols);
var tabData = tabDataRange.getValues(); // <-- REMOVE DUPLICATES
for (var i = 0; i < tabData.length; i++) {
if (tabData[0][i] != "" && tabData[0][i] > version) {
for (var j = 0; j < tabData.length; j++) {
if (tabData[j][i] != "" && j > 0) {
Logger.log("tabData[j][i] = " + tabData[j][i]); // tabData[j][i] = all values in column
}
}
}
}
}
This is the array it currently produces:
2.20200514.2,2.20200514.0,2.20200513.2,2.20200513.1,2.20200513.0,2.20200512.0,1.20200405.1,,tabDefinitions,Sheet6,Sheet6,changeLog,Sheet6,Index,,,,Sheet7,,Sheet7,settings,,,,Sheet8,,Sheet8,tabDefinitions,,,,,,,changeLog,,,,,,,updateTabs
I want to remove all duplicates (Sheet6, Sheet7, Sheet8, etc.) from the array.
EDIT:
After one more search, I found this answer which contains exactly what was answered below, but when I use any method in that answer, I still get all duplicates. Not sure what I'm doing wrong or not doing right.
var unique = tabData.filter((v, i, a) => a.indexOf(v) === i);
EDIT 2:
I realized my array was not actually "flat", so I added var tabData = tabDataRange.getValues().flat(); and now everything works!
You can use ES6 Set() function to remove the duplicates
const newArray = [...new Set(arrayWithDuplicates)];
So, I have following js setup:
var NAMES = [];
function INFO(id,first,middle,last){
var newMap = {};
newMap[id] = [first, middle, last];
return newMap ;
}
Then,
for (var j = 0; j < NUMBER.length; j++) { //let say it there are three values
var my_name = all_names[j]; // has "185, 185, 185"
if (NAMES[my_name] !== 185){ //Needs to check here
NAMES.push(INFO(my_name,"sean","sdfsd","sdfsfd"));
}else{
}
}
alert(JSON.stringify(NAMES , null, 4));
Here is a screenshot of the alert:
I hardcoded the number "185" for this example. I need to check if the id of 185 exists, then skip to else. I am not sure how to check it. I tried typeof, undefinedetc. but no luck.
(In other words, I should only have one "185").
Any help? Thanks!
If I understood correctly what you are trying to achieve, you have to iterate over NAMES and check every element. For example, you could do it using [].some javascript function:
if (!NAMES.some(function(v){return v[my_name]})) {
...
} else {
}
If you want to remove duplication you can just use NAMES as an object instead of array like this
var all_names = [185, 185, 181],
NAMES = {};
for (var j = 0; j < all_names.length; j++) { //let say it there are three values
var my_name = all_names[j]; // has "185, 185, 185"
NAMES[my_name] = ["sean","sdfsd","sdfsfd"];
}
alert(JSON.stringify(NAMES, null, 4));
First of all I would recommend making a JS Fiddle or CodePen out of this so people can see the code running.
I believe that the issue is that NAMES[my_name] is not doing what you think it is. NAMES is an Array so when you say NAMES[my_name] you are really asking for the ITEM in the array so you are getting the entire object that you create in the INFO function. What you really want is to see if the object has an attribute that matches the value (e.g. "185" from the my_names array).
This is not the prettiest code but it will show you how to do what you really want to do:
var NAMES = [];
function INFO(id,first,middle,last){
var newMap = {};
newMap[id] = [first, middle, last];
return newMap ;
}
all_names = ["185", "186", "185"]
for (var j = 0; j < all_names.length; j++) {
var my_name = all_names[j];
if (NAMES.length == 0) {
NAMES.push(INFO(my_name,"sean","sdfsd","sdfsfd"));
} else {
var match = false;
for (var x = 0; x < NAMES.length; x++) {
console.log(NAMES[x][my_name] + ' : ' + my_name);
if(NAMES[x][my_name]) {
match = true;
}
}
if (!match) {
NAMES.push(INFO(my_name,"sean","sdfsd","sdfsfd"));
}
}
}
alert(JSON.stringify(NAMES , null, 4));
Note the if that looks at NAMES[x][my_name] - this is asking if the item at array index 'x' has an attribute of 'my_name' (e.g. "185"). I believe this is really what you are trying to do. As its after midnight I assure you that there is more concise and pretty JS to do this but this should show you the basic issue you have to address.
Try this code using hasOwnProperty method :
for (var j = 0; j < NUMBER.length; j++) { //let say it there are three values
var my_name = all_names[j]; // has "185, 185, 185"
if (!NAMES[my_name].hasOwnProperty("185")){ //Needs to check here
NAMES.push(INFO(my_name,"sean","sdfsd","sdfsfd"));
}else{
}
}
I'm attempting to teach myself javascript. I chose something I assumed was simple, but ran into problems relatively quickly.
I'm attempting to search a string for another string given by the user.
My code so far is:
var source = "XREs2qqAQfjr6NZs6H5wkZdOES5mikexRkOPsj6grQiYNZfFoqXI4Nnc1iONKVrA";
var searchString = []; //the users input
searchString = prompt("Enter search string");
var hits = [];
var one = 0;
var two = 0;
var k = 0;
var sourceSearch = function(text) {
for(i = 0; i < source.length; i++) { //for each character in the source
if(source[i] === searchString[0]) { //if a character in source matches the first element in the users input
one = source.indexOf(i); //confused from here on
for(p = searchString.length; p > 0; p--) {
}
}
}
};
sourceSearch(searchString);
My idea was:
check to see if the first loop finds a character that matches the first character in the user input
if it matches, check to see if the next X characters after the first match the next X characters in the source string
if they all match, push them to the hits array
My problem: I have no idea how to iterate along the arrays without nesting quite a few if statements, and even then, that wouldn't be sufficient, considering I want the program to work with any input.
Any ideas would be helpful. Thanks very much in advance.
Note: There are a few un-used variables from ideas I was testing, but I couldn't make them work.
You can try:
if (source.indexOf(searchString) !== -1) {
// Match!
}
else
{
//No Match!
}
As the other answers so far point out, JavaScript strings have an indexOf function that does what you want. If you want to see how it's done "by hand", you can modify your function like this:
var sourceSearch = function(text) {
var i, j, ok; // always declare your local variables. globals are evil!
// for each start position
for(i = 0; i < source.length; i++) {
ok = true;
// check for a match
for (j = searchString.length - 1; ok && j >= 0; --j) {
ok = source[i + j] === searchString[j];
}
if (ok) {
// searchString found starting at index i in source
}
}
};
This function will find all positions in source at which searchString was found. (Of course, you could break out of the loop on the first success.) The logic is to use the outer loop to advance to each candidate start position in source and use the inner loop to test whether that position actually is the position of a match to searchString.
This is not the best algorithm for searching strings. The built-in algorithm is much faster (both because it is a better algorithm and because it is native code).
to follow your approach, you can just play with 2 indexes:
var sourceSearch = function(text) {
j = 0;
for(i = 0; i < source.length; i++) {
if(source[i] === text[j]) {
j++;
} else {
j = 0;
}
if (j == text.length) {
console.log(i - j); //this prints the starting index of the matching substring
}
}
};
These answers are all pretty good, but I'd probably opt for something like this:
var source = "XREs2qqAQfjr6NZs6H5wkZdOES5mikexRkOPsj6grQiYNZfFoqXI4Nnc1iONKVrA";
var searchString = []; //the users input
searchString = prompt("Enter search string");
var hits = source.split(searchString);
var hitsCount = hits.length - 1;
This way you have all of the data you need to figure out where each hit occurred in he source, if that's important to you.
(forgive me if I use slightly incorrect language - feel free to constructively correct as needed)
There are a couple posts about getting data from JSON data of siblings in the returned object, but I'm having trouble applying that information to my situation:
I have a bunch of objects that are getting returned as JSON from a REST call and for each object with a node of a certain key:value I need to extract the numeric value of a sibling node of a specific key. For example:
For the following list of objects, I need to add up the numbers in "file_size" for each object with matching "desc" and return that to matching input values on the page.
{"ResultSet":{
Result":[
{
"file_size":"722694",
"desc":"description1",
"format":"GIF"
},
{
"file_size":"19754932",
"desc":"description1",
"format":"JPEG"
},
{
"file_size":"778174",
"desc":"description2",
"format":"GIF"
},
{
"file_size":"244569996",
"desc":"description1",
"format":"PNG"
},
{
"file_size":"466918",
"desc":"description2",
"format":"TIFF"
}
]
}}
You can use the following function:
function findSum(description, array) {
var i = 0;
var sum = 0;
for(i = 0; i < array.length; i++) {
if(array[i]["desc"] == description && array[i].hasOwnProperty("file_size")) {
sum += parseInt(array[i]["file_size"], 10);
}
}
alert(sum);
}
And call it like this:
findSum("description1", ResultSet.Result);
To display an alert with the summation of all "description1" file sizes.
A working JSFiddle is here: http://jsfiddle.net/Q9n2U/.
In response to your updates and comments, here is some new code that creates some divs with the summations for all descriptions. I took out the hasOwnProperty code because you changed your data set, but note that if you have objects in the data array without the file_size property, you must use hasOwnProperty to check for it. You should be able to adjust this for your jQuery .each fairly easily.
var data = {};
var array = ResultSet.Result;
var i = 0;
var currentDesc, currentSize;
var sizeDiv;
var sumItem;
//Sum the sizes for each description
for(i = 0; i < array.length; i++) {
currentDesc = array[i]["desc"];
currentSize = parseInt(array[i]["file_size"], 10);
data[currentDesc] =
typeof data[currentDesc] === "undefined"
? currentSize
: data[currentDesc] + currentSize;
}
//Print the summations to divs on the page
for(sumItem in data) {
if(data.hasOwnProperty(sumItem)) {
sizeDiv = document.createElement("div");
sizeDiv.innerHTML = sumItem + ": " + data[sumItem].toString();
document.body.appendChild(sizeDiv);
}
}
A working JSFiddle is here: http://jsfiddle.net/DxCLu/.
That's an array embedded in an object, so
data.ResultSet.Result[2].file_size
would give you 778174
var sum = {}, result = ResultSet.Result
// Initialize Sum Storage
for(var i = 0; i < result.length; i++) {
sum[result[i].desc] = 0;
}
// Sum the matching file size
for(var i = 0; i < result.length; i++) {
sum[result[i].desc] += parseInt(result[i]["file_size"]
}
After executing above code, you will have a JSON named sum like this
sum = {
"description1": 20477629,
"description2": 1246092
};
An iterate like below should do the job,
var result = data.ResultSet.Result;
var stat = {};
for (var i = 0; i < result.length; i++) {
if (stat.hasOwnProperty(result[i].cat_desc)) {
if (result[i].hasOwnProperty('file_size')) {
stat[result[i].cat_desc] += parseInt(result[i].file_size, 10);
}
} else {
stat[result[i].cat_desc] = parseInt(result[i].file_size, 10);
}
}
DEMO: http://jsfiddle.net/HtrLu/1/
I have been searching online all day and I cant seem to find my answer. (and I know that there must be a way to do this in javascript).
Basically, I want to be able to search through an array of objects and return the object that has the information I need.
Example:
Each time someone connects to a server:
var new_client = new client_connection_info(client_connect.id, client_connect.remoteAddress, 1);
function client_connection_info ( socket_id, ip_address, client_status) {
this.socket_id=socket_id;
this.ip_address=ip_address;
this.client_status=client_status; // 0 = offline 1 = online
};
Now, I want to be able to search for "client_connection.id" or "ip_address", and bring up that object and be able to use it. Example:
var results = SomeFunction(ip_address, object_to_search);
print_to_screen(results.socket_id);
I am new to javascript, and this would help me dearly!
Sounds like you simply want a selector method, assuming I understood your problem correctly:
function where(array, predicate)
{
var matches = [];
for(var j = 0; j < array.length; j++)
if(predicate(j))
matches.push(j);
return matches;
}
Then you could simply call it like so:
var sample = [];
for(var j = 0; j < 10; j++)
sample.push(j);
var evenNumbers = where(sample, function(elem)
{
return elem % 2 == 0;
});
If you wanted to find a specific item:
var specificguy = 6;
var sixNumber = where(sample, function(elem)
{
return elem == specificguy;
});
What have you tried? Have you looked into converting the data from JSON and looking it up as you would in a dictionary? (in case you don't know, that would look like object['ip_address'])
jQuery has a function for this jQuery.parseJSON(object).
You're going to need to loop through your array, and stop when you find the object you want.
var arr = [new_client, new_client2, new_client3]; // array of objects
var found; // variable to store the found object
var search = '127.0.0.1'; // what we are looking for
for(var i = 0, len = arr.length; i < len; i++){ // loop through array
var x = arr[i]; // get current object
if(x.ip_address === search){ // does this object contain what we want?
found = x; // store the object
break; // stop looping, we've found it
}
}