How do I move an object from one array to another? - javascript

I'm trying to move an object from one array(triviaDataArray) to another(answeredQuestions). I've replaced the actual questions with numbers to shorten code. When I run this code it seems to remove a position in the triviaDataArray, and adds one to the answeredQuestion array. But it doesn't seem to remove the correct one. When a new question is loaded it sometimes repeats itself, which is not what I want. I want it to ask a question, and then when it is answered move it to the answeredQuestion array.
I can only use JavaScript. Can someone please help me. I've been struggling with this for quite some time.
This portion is from a data reader file I have to load a random question and it's answers from an array and the second is to open the array.
TriviaDataRecords.prototype.loadRandomRecord = function () {
this.position = Math.floor(Math.random() * this.records.length);
};
function openTriviaRecords(triviaData) {
return new TriviaDataRecords(triviaData);
}
global arrays and variables
var triviaDataArray = [1, 2, 3, 4, 5, 6, 7]
var answeredQuestions = []
var triviaRecords = openTriviaRecords(triviaDataArray);
function that loads a question and files the fields of the html.
function loadQuestion(){
var randomRecord = triviaRecords.loadRandomRecord();
var buttonA = document.getElementById("answer1");
var buttonB = document.getElementById("answer2");
var buttonC = document.getElementById("answer3");
var buttonD = document.getElementById("answer4");
var buttonE = document.getElementById("answer5");
document.getElementById('question').innerHTML = triviaRecords.getQuestion();
document.getElementById('answer1').innerHTML = triviaRecords.getAnswerA();
document.getElementById('answer2').innerHTML = triviaRecords.getAnswerB();
document.getElementById('answer3').innerHTML = triviaRecords.getAnswerC();
document.getElementById('answer4').innerHTML = triviaRecords.getAnswerD();
document.getElementById('answer5').innerHTML = triviaRecords.getAnswerE();
portion where I'm trying to move the question from one array to another.
var index = triviaDataArray.indexOf(randomRecord);
if (index == -1) {
triviaDataArray.splice(randomRecord, 1);
answeredQuestions.push(randomRecord);
}

Related

When using different variables, both arrays get modified

So I was doing a little search engine for Google Sheets and I didn't want it to be case sensitive, so I make it declare "RealComments" as the actual content to be retrieved and then proceed to lowercase the "Comments" array row by row on the main loop.
It sounds to me like a no brainier that it should work, they are different variables and I'm returning the RealComments, not the Comments. But some kind of weird quantum entanglement is going on in my code because no matter how I declare it, every time I apply toLowecase() to either the RealComments or Comments arrays both get modified.
I have no clue why that is or how to fix it. Here's the full code:
/**
* Searches for relevant questions and answers
*
* #param {cell} Keywords Cell with comma separated list
* #param {cell} Query Cell with text in question format
* #param {cell} Type Validation cell with options, leave "Any" for no filter
* #param {column} TypeOfComment Array with the type of question column
* #param {array} Comments Array with the questions and answers in two columns
* #param {column} ScreenshotLinks Array with the screenshot link column
* #return Your answer. :)
* #customfunction
*/
function SearchQuery(Keywords,Query,Type,TypeOfComment,Comments,ScreenshotLinks) {
if(Keywords==""){
return "Please type your query/keywords above for results to be displayed here."
}
var ResultArray = [];
var Score = 0;
var MinimumScore = 2;
var MinimumScorePosition = 0;
var keywords = [];
var querywords = [];
var RealComments = Comments;
for(rows in RealComments){
RealComments[rows].push(ScreenshotLinks[rows][0]);
}
var RemaneingKeywords = CleanPunctuation(Keywords);
var RemaneingQuery = CleanPunctuation(Query);
var NextSpace = RemaneingKeywords.indexOf(' ');
while(NextSpace != -1){
keywords.push(RemaneingKeywords.substr(0,NextSpace));
RemaneingKeywords = RemaneingKeywords.substr(NextSpace+1,RemaneingKeywords.length);
NextSpace = RemaneingKeywords.indexOf(' ');
}
keywords.push(RemaneingKeywords);
NextSpace = RemaneingQuery.indexOf(' ');
while(NextSpace != -1){
querywords.push(RemaneingQuery.substr(0,NextSpace));
RemaneingQuery = RemaneingQuery.substr(NextSpace+1,RemaneingQuery.length);
NextSpace = RemaneingQuery.indexOf(' ');
}
querywords.push(RemaneingQuery);
for(rows in Comments){
Comments[rows][0] = Comments[rows][0].toLowerCase(); //Investigate lowercase glitch
Comments[rows][1] = Comments[rows][1].toLowerCase();
if(Type=="Any"||TypeOfComment[rows]==Type){
Score = 0;
for(keyword in keywords){
if(Comments[rows][0].indexOf(keywords[keyword])!=-1||Comments[rows][1].indexOf(keywords[keyword])!=-1){
Score = Score+10;
}
}
for(words in querywords){
if(Comments[rows][0].indexOf(querywords[words])!=-1||Comments[rows][1].indexOf(querywords[words])!=-1){
Score = Score+1;
}
}
if(ResultArray.length<20 && Score>2){
ResultArray.push(RealComments[rows]);
ResultArray.push(Score);
MinimumScore = FindMinimumScore(ResultArray);//Math.min.apply(null,ResultArray);
}
else{if(Score>MinimumScore){
MinimumScorePosition = ResultArray.indexOf(MinimumScore);
ResultArray.splice(MinimumScorePosition-1,2);
ResultArray.push(RealComments[rows]);
ResultArray.push(Score);
MinimumScore = FindMinimumScore(ResultArray);
}}
}
}
var ScoresForSorting = []; //Sorting the responses here
for(i=0;i<10;i++){
if(ResultArray[i+1]==undefined){ScoresForSorting.push(-2);}
else{ScoresForSorting.push(parseInt(ResultArray.splice(i+1,1)));}
}
var ResponseOrder = [];
for(i=0;i<10;i++){
MinimumScorePosition = ScoresForSorting.indexOf(Math.max(ScoresForSorting[0],ScoresForSorting[1],ScoresForSorting[2],ScoresForSorting[3],ScoresForSorting[4],ScoresForSorting[5],ScoresForSorting[6],ScoresForSorting[7],ScoresForSorting[8],ScoresForSorting[9]));
ResponseOrder.push(MinimumScorePosition);
ScoresForSorting[MinimumScorePosition]=-3;
}
var SortedResultArray = [];
for(results in ResponseOrder){
SortedResultArray.push(ResultArray[ResponseOrder[results]]);
}
if(SortedResultArray[0]==undefined){SortedResultArray = []; SortedResultArray.push("Sorry, No Result Was Found To Your Search. ) : ");}
return SortedResultArray
}
function FindMinimumScore(ResultArray){
return Math.min(ResultArray[1],ResultArray[3],ResultArray[5],ResultArray[7],ResultArray[9],ResultArray[11],ResultArray[13],ResultArray[15],ResultArray[17],ResultArray[19])
}
function CleanTwoLetterWords(words){
var badwords = ["do","in","at","it","of","as","be","if","or","we","by","an","or","no","my","vs"];
for(badword in badwords){words = words.replace(badwords[badword],"");}
return words
}
function CleanThreeLetterWords(words){
if(parseInt(words)>9){return ""} //remove numbers
var badwords = ["and","for"];
for(badword in badwords){words = words.replace(badwords[badword],"");}
return words
}
function CleanPunctuation(words){
words = words.toLowerCase();
var badlettergroup = ["{","}",",",":","+","-","™","®","?","!","(",")","'"];
for(letter in badlettergroup){while(words.indexOf(badlettergroup[letter]) != -1){words = words.replace(badlettergroup[letter]," ");}}
return words
}
function MakeThingsSingular(words){
var exceptions = ["this"];
if(exceptions.indexOf(words) != -1){return words}
var wordl = words.length;
if(words.substr(wordl-1,wordl) == "s" && words.substr(wordl-2,wordl) != "ss"){return words.substr(0,wordl-1)}
return words
}
I wrote it all myself, but I don't think any of this is particularly brilliant so feel free to copy. Also, to suggest improvements if you have any. But most important of all, if you have any idea why the lines making the Comments array lowercased would be affecting RealComments and/or how to fix it, please let me know.
EDIT:
So after some more research and helpful answers I've tried declarying RealComments as:
var RealComments = [];
for(rows in Comments){
RealComments.push(Comments[rows]);
}
On which case the glitch persists.
var RealComments = [...Comments];
Which returns a syntax error.
var RealComments = Comments.slice();
In which case the glitch still persists.
...
So basically, I still don't understand what's wrong with the code, commenting out the either of the lowercase lines affects the column you'd expect on the RealComments as if they were still linked.
Comments[rows][0] = Comments[rows][0].toLowerCase();
Comments[rows][1] = Comments[rows][1].toLowerCase();
So I guess this post if not yet solved... But thank you for all the replies up to now.
In javascript Array assignment creates reference not copy.
if you do
var a = [1,2,3,4];
var b = a;
b will be the reference for a. It means if you modify b, it is actually gonna modify a.
QUICK SOLUTION
in the line where you are doing
var RealComments = Comments;
Do this instead var RealComments = Comments.slice();
As long as Comments is an array slice method will return a new instance of Comments array. So modifying RealComments won't modify Comments anymore.
TheMaster pointed out that "slice() won't work, because Comments is not a array, but array of arrays.". After which the solution that did it for me was just using:
var newArray = JSON.parse(JSON.stringify(orgArray));
Which in my case was:
var RealComments = JSON.parse(JSON.stringify(Comments));
Thank you for all the help! I hope this helps other users.

Why is this JavaScript looping twice in Zapier?

Here is a video that shows what I'm struggling with.
Here is a high level description of the process, followed by the actual JavaScript code I've written.
PROCESS
I built 2 Zaps that each run like this:
STEP 1 - Trigger (Cognito Form, which has repeating sections)
STEP 2 - JavaScript Code (which creates an Array of the form fields for ONE of the repeating sections, and separates them into individual strings using .split)
STEP 3 - Action (creates a ZOHO CRM Task for each string)
The first Zap runs on one of the sections of the form (Visits with Sales), and the second zap runs on a different section of the form (Visits without Sales). Each of these Zaps works fine on their own so I know the code is good, but I want to combine the two Zaps into one by combining the code.
I tried to combine by making five steps:
Trigger - Code1 - Zoho1 - Code2 - Zoho2
but the Zoho2 Tasks were each repeated
I then tried to re-order the five steps:
Trigger - Code1 - Code2 - Zoho1 - Zoho2
but now Zoho1 Tasks AND Zoho2 tasks were duplicated.
Finally I tried to combine ALL the JavaScript code into one:
Tigger - CombinedCode1+2 - Zoho 1 - Zoho2
but only the strings from Arrays in "Code2" are available to me when I go to map them in Zoho1.
CODE:
if (inputData.stringVSAccount == null) {
var listVSAccountArray = [];
var listVSUnitsArray = [];
var listVSPriceArray = [];
var listVSNotesArray = [];
var listVSVisitCallArray = [];
} else {
var listVSAccountArray = inputData.stringVSAccount.split(",");
var listVSUnitsArray = inputData.stringVSUnits.split(",");
var listVSPriceArray = inputData.stringVSPrice.split(",");
var listVSNotesArray = inputData.stringVSNotes.split(",");
var listVSVisitCallArray = inputData.stringVSVisitCall.split(",");
}
var output = [];
var arrayNos = listVSAccountArray.length;
var i = 0;
do {
var thisItemVSAccount = new String(listVSAccountArray[i]);
var thisItemVSUnits = new String(listVSUnitsArray[i]);
var thisItemVSPrice = new String(listVSPriceArray[i]);
var thisItemVSNotes = new String(listVSNotesArray[i]);
var thisItemVSVisitCall = new String(listVSVisitCallArray[i]);
var thisItemObj = {};
thisItemObj.itemVSAccount = thisItemVSAccount;
thisItemObj.itemVSUnits = thisItemVSUnits;
thisItemObj.itemVSPrice = thisItemVSPrice;
thisItemObj.itemVSNotes = thisItemVSNotes;
thisItemObj.itemVSVisitCall = thisItemVSVisitCall;
output.push({ thisItemObj });
i++;
} while (i < arrayNos);
//This is where the second zaps code is pasted in the combined version
if (inputData.stringOVAccount == null) {
var listOVAccountArray = [];
var listOVNotesArray = [];
var listOVVisitCallArray = [];
} else {
var listOVAccountArray = inputData.stringOVAccount.split(",");
var listOVNotesArray = inputData.stringOVNotes.split(",");
var listOVVisitCallArray = inputData.stringOVVisitCall.split(",");
}
var output = [];
var arrayNos = listOVAccountArray.length;
var i = 0;
do {
var thisItemOVAccount = new String(listOVAccountArray[i]);
var thisItemOVNotes = new String(listOVNotesArray[i]);
var thisItemOVVisitCall = new String(listOVVisitCallArray[i]);
var thisItemObj = {};
thisItemObj.itemOVAccount = thisItemOVAccount;
thisItemObj.itemOVNotes = thisItemOVNotes;
thisItemObj.itemOVVisitCall = thisItemOVVisitCall;
output.push({ thisItemObj });
i++;
} while (i < arrayNos);
I just started learning JavaScript this week, and sense that I am missing something obvious, perhaps a set of brackets. Thanks for any assistance
David here, from the Zapier Platform team. You're running into a confusing and largely undocumented feature where items after a code step run for each item returned. This is usually desired behavior - when you return 3 submissions you want to create 3 records.
In your case, it's also running subsequent unrelated actions multiple times, which sounds like it's undesired. In that case, it might be easier to have 2 zaps. Or, if "Zoho2" only ever happens once, put it first and let the branch happen downstream.
Separately, I've got some unsolicited javascript advice (since you mentioned you're a beginner). Check out Array.forEach (docs), which will let you iterate through arrays without having to manage as many variables (your own i every time). Also, try to use let and const over var when possible - it keeps your variables scoped as small as possible so you don't accidentally leak values into other areas.
​Let me know if you've got any other questions!
Just a note - you are declaring the same array variable output in both segments of your code block - the second declaration will be ignored.
Use the .forEach() method to iterate over your arrays, it will significantly cleanup you code. You also don't need to painstakingly construct the objects to be pushed into the output arrays.
This may not fix your issue but the code is far easier on the eye.
var listVSAccountArray = [],
listVSUnitsArray = [],
listVSPriceArray = [],
listVSNotesArray = [],
listVSVisitCallArray = [],
output = [];
if (typeof inputData.stringVSAccount === 'string') {
listVSAccountArray = inputData.stringVSAccount.split(',');
listVSUnitsArray = inputData.stringVSUnits.split(',');
listVSPriceArray = inputData.stringVSPrice.split(',');
listVSNotesArray = inputData.stringVSNotes.split(',');
listVSVisitCallArray = inputData.stringVSVisitCall.split(',');
}
// iterate over the array using forEach()
listVSAccountArray.forEach(function(elem, index){
// elem is listVSAccountArray[index]
output.push({
itemVSAccount: elem,
itemVSUnits: listVSUnitsArray[index],
itemVSPrice: listVSPriceArray[index],
itemVSNotes: listVSNotesArray[index],
itemVSVisitCall: listVSVisitCallArray[index]
})
})
//This is where the second zaps code is pasted in the combined version
var listOVAccountArray = [],
listOVNotesArray = [],
listOVVisitCallArray = [],
output_two = []; // changed the name of the second output array
if (typeof inputData.stringOVAccount === 'string') {
listOVAccountArray = inputData.stringOVAccount.split(',');
listOVNotesArray = inputData.stringOVNotes.split(',');
listOVVisitCallArray = inputData.stringOVVisitCall.split(',');
}
// iterate over the array using forEach()
listOVAccountArray.forEach(function(elem, index){
// elem is listOVAccountArray[index]
output_two.push({
itemOVAccount: elem,
itemOVNotes: listOVNotesArray[index],
itemOVVisitCall: listOVVisitCallArray[index]
});
});

Putting an object into an array in JavaScript

I'm currently working with an MVC JS framework and I want to be able to get a list of objects that I can take a random entry out of on a loop. So far I've managed to create a function that finds a random ID and pulls out that object so that part is not a problem. It's what is going into the array of objects:
QuestionsSetup: function(gameType) {
// Setup Resources
var c = this.View.children;
var player1qs = [];
var leftQ = 0;
var rightQ = 0;
var maxQValue = 50;
var minQValue = 1;
// Fill array with questions
for (var i = 0; i < 5; i++) {
// Build a random question with numbers between 1 and 50
// Build Question Text to output to user
// Generate correct answers based on generated question
// Generate unsorted, incorrect answers and add them to an array
//Place Questions into object
questions.qId = i;
questions.leftQ = leftQ;
questions.rightQ = rightQ;
questions.correctAnswer = correctAnswer;
questions.allAnswers = sortedAnswers;
questions.questionText = questionText;
//Add to array of questions
player1qs.push(questions);
}
}
This does add them to an array but when adding a new object it also changes the values of the existing objects in the array so they all come out the same no matter which one I pull out later. The questions object is declared in it's own file in a models folder. Is there any way, at the start of each loop, to tell the application I want new empty questions object as opposed to referencing the existing ones? I know that you can in similar back end languguages so I refuse to beleive that something so simple doesn't exist in JavaScript too?
Declaring a variable for each array item is definitely missing.
QuestionsSetup: function(gameType) {
// Setup Resources
var c = this.View.children;
var player1qs = [];
var leftQ = 0;
var rightQ = 0;
var maxQValue = 50;
var minQValue = 1;
// Fill array with questions
for (var i = 0; i < 5; i++) {
var tempQuestion = {
qId: i,
leftQ: leftQ,
rightQ: rightQ,
correctAnswer: correctAnswer,
allAnswers: sortedAnswers,
questionText: questionText
}
// ...
//Add to array of questions
player1qs.push(tempQuestion);
}
}
Using a separate closure inside a loop also might be a good idea.
do this:
for (var i = 0; i < 5; i++) {
let questions = {};
// the rest....
you need to define the object first.
Maybe you should just initialize the questions object before initializing its properties, so the code should look like this:
//Place Questions into object
questions = {};
questions.qId = i;
questions.leftQ = leftQ;
questions.rightQ = rightQ;
questions.correctAnswer = correctAnswer;
questions.allAnswers = sortedAnswers;
questions.questionText = questionText;
//Add to array of questions
player1qs.push(questions);

How to get variable from different function [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 7 years ago.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
So what I'm trying to do is get a search term from one function getRandomVideo() and use it in a jQuery statement, so for example, get beethoven from the variable searches and use it as the search term to get back JSON information and append it to a div. I know next to nothing about jQuery so any help would be great thanks :)
<script type="text/javascript">
function getRandomVideo() {
var videos = [
'https://www.youtube.com/embed/kiTO7c_qeZs',
'https://www.youtube.com/embed/z4Hfv00eqoI',
'https://www.youtube.com/embed/7cdZYQB5ONE',
'https://www.youtube.com/embed/i1gE3nyQnKg',
];
var titles = [
'Beethoven - Music, Love and Wine',
'Mozart String Serenade No.13',
'Beethoven Sonata No. 31 in A Flat Major',
"Debussy - Children's Corner",
];
var images = [
"url('Assets/beethoven.jpg')",
"url('Assets/mozart.jpg')",
"url('Assets/beethoven.jpg')",
"url('Assets/debussy.jpg')",
]
var searches = [
'beethoven',
'mozart',
'beethoven',
'debussy',
]
var rand = Math.floor(Math.random()*videos.length);
var video = videos[rand];
var title = titles[rand];
var image = images[rand];
var search = searches[rand];
document.getElementById("songTitle").innerHTML = title;
document.getElementById("img").style.backgroundImage = image;
var htmlVideo = document.getElementById("randomVideo");
htmlVideo.src = video;
htmlVideo.onload=null;
return search
}
getRandomVideo();
$(document).ready(function(){
// Im not sure what to do here to get it to run when the page starts
// Get the value from our getRandomVideo()
var searchTerm = getRandomVideo();
var url = "http://api.trove.nla.gov.au/result?key=jja10ssv4950uh65&encoding=json&zone=newspaper&sortby=relevance&q=" + searchTerm + "&s=0&n=5&include=articletext,pdf&encoding=json&callback=?";
/*
* Perform the search using jQuery's getJSON method
* Requires the search URL
*/
console.log(url);
$.getJSON(url, function(data) {
$.each(data.response.zone[0].records.article, function(index, value) {
$("#output").append("<p>" + value.articleText +"</p>");
});
});
};
</script>
This should give you an idea as to how to accomplish this...
var getRandomVideo = (function(){
var _videos = [
'https://www.youtube.com/embed/kiTO7c_qeZs',
'https://www.youtube.com/embed/z4Hfv00eqoI',
'https://www.youtube.com/embed/7cdZYQB5ONE',
'https://www.youtube.com/embed/i1gE3nyQnKg',
];
var _titles = [
'Beethoven - Music, Love and Wine',
'Mozart String Serenade No.13',
'Beethoven Sonata No. 31 in A Flat Major',
"Debussy - Children's Corner",
];
var _images = [
"url('Assets/beethoven.jpg')",
"url('Assets/mozart.jpg')",
"url('Assets/beethoven.jpg')",
"url('Assets/debussy.jpg')",
];
var _searches = [
'beethoven',
'mozart',
'beethoven',
'debussy',
];
return {
videos: function(){ return _videos; },
titles: function(){ return _titles; },
images: function(){ return _images; },
searches: function(){ return _searches; }
};
})(); // this is the module pattern FYI
var rand = Math.floor(Math.random() * getRandomVideo.videos().length);
var video = getRandomVideo.videos()[rand];
var title = getRandomVideo.titles()[rand];
var image = getRandomVideo.images()[rand];
var search = getRandomVideo.searches()[rand];
document.getElementById("songTitle").innerHTML = title;
document.getElementById("img").style.backgroundImage = image;
var htmlVideo = document.getElementById("randomVideo");
In javascript, everything including variables are scoped by function so any variable declared inside a function such as...
function myFunction()
{
var a1 = "something";
}
var test = a1; // a1 would be undefined as it is out of scope of `myFunction()` so test would be too of course
By using the module pattern, you can expose properties/functions within the return{}; statement. NB: the underscores are just to identify private functions/objects etc ;)
Also if you were to do the below, you would be able to access a1 as it would cascade into global scope as it has not been declared...
function myFunction()
{
a1 = "something";
}
var test = a1; // a1 would be "something"
But I wouldn't suggest this... for a number of architectural reasons :-/

jquery get the unreapeatable values

i have a array with numbers. i need that array value to be generated once i click on the button, while i click on the button i need to get the value random wise from the array, but the value should not be repeated.
ex, if i get a 2 from out of 5, then i should not get the 2 again. for this i wrote this function, but the values are repeating... any idea?
var ar = [0,1,2,3,4,5];
var ran = Math.floor(Math.random()*ar.length);
ar.splice(ran,1);
alert(ar.splice);
the array values should not be removed. because if i click the button again, i need to get the values like before.
i did my work like this : but the rand values are repeating, any one can correct this to get unrepeatable values to get?
$(document).ready(function(){
var myArray = [1,2,3,4,5];
var mySize = 5;
x = 0;
while(mySize>=1){
var rand = Math.floor(Math.random()*mySize);
mySize--;
alert(rand);
}
})
You need your array to be in an outer scope for this like:
(function(){
var ar = [0,1,2,3,4,5];
document.getElementById('thebutton').onclick = function(){
alert(ar.splice(Math.floor(Math.random()*ar.length), 1));
};
})();
JSFiddle Example
If you create your array inside the onclick function then you are just recreating the entire array every time the button is clicked.
Take a look at this demo. In this it randomizes the array values and will repeat only after all the values are utilized.
Demo
Based on the update in your question here it is take a look.
http://jsfiddle.net/MbkwK/2/
var ar = [0, 1, 2, 3, 4, 5];
document.getElementById('thebutton').onclick = function() {
var shuffle = [];
var copyarr = ar.slice(0);
var arlength = copyarr.length;
for (i = 0; i < arlength; i++) {
shuffle.push(copyarr.splice(Math.floor(Math.random() * copyarr.length), 1));
}
alert(shuffle.join(","));
};
Working demo - http://jsfiddle.net/ipr101/qLSud/1/

Categories

Resources