Iterate a function until result from called function is equal, javascript - javascript

I need to iterate a function several times until it returns same thing twice.
This needs to go into a for-loop somehow but I can't get my head around how to this. Here's some code with 4 manual iterations. Any ideas how to put this in a for-loop?
Velocity.prototype.removeCombinedDistancesThatAreShorterThanTrainLength = function(wayPoints, lengthOfTrain){
var firstTry = this.removeWayPointsWhichAreShorterThenTrainLength(wayPoints, lengthOfTrain);
var secondTry = this.removeWayPointsWhichAreShorterThenTrainLength(firstTry, lengthOfTrain);
if(firstTry === secondTry){
return firstTry;
}else{
var thirdTry = this.removeWayPointsWhichAreShorterThenTrainLength(secondTry, lengthOfTrain);
if(thirdTry === secondTry){
return secondTry
}else{
var forthTry = this.removeWayPointsWhichAreShorterThenTrainLength(thirdTry, lengthOfTrain);
if(thirdTry === forthTry){
return forthTry
}
}
}
return forthTry;
};

Something like this (not tried, but should give you the general idea):
var lastTry = null;
var thisTry = wayPoints;
do
{
lastTry = thisTry;
thisTry = this.removeWayPointsWhichAreShorterThenTrainLength(lastTry, lengthOfTrain);
} while (lastTry !== thisTry);
If it's possible that the result will never become equal, consider implementing a safeguard for this, like a maximum number of iterations.

Related

how to itereate an json object in angularjs using for loop?

I have one array i want to iterate that in the iteration process we check one condition if condition is true we return one value otherwise we return else part I write some code but its not working.
the loop will not terminated if condition is true how can i do that cam anyone help me?
$scope.bgImages = []; //it having some objects
$scope.job = []; //it also having some objeccts
//if both elements are matching we return one value
$scope.getJobDepartmentImg = function() {
var jobDepartment = $scope.job.department;
for (var i in $scope.bgImages) {
var department = $scope.bgImages[i].departmentName;
var job_header = $scope.bgImages[i].s3ImageUrl;
if (jobDepartment === department) {
return job_header;
} else {
return default_job_header;
}
}
};
The loop is not terminated if condition is satisfiedd that method will continiouslyy can anyone help me?
put an second return outside else statement
$scope.getJobDepartmentImg = function() {
var jobDepartment = $scope.job.department;
for (var i in $scope.bgImages) {
var department = $scope.bgImages[i].departmentName;
var job_header = $scope.bgImages[i].s3ImageUrl;
if(jobDepartment === department){
return job_header;
}
}
return default_job_header;
}
it will iterate through array and return job_header if it finds one, or return default if loop ends

Finding a cycle in singly linked list with javascript (Is my solution efficient)

My solution works well if the starting node is passed to the function correctly. I want to know if my solution is good and efficient. I should be able to return true if the cycle exists via function to which first node is passed as parameter. I would like to know if my solution is efficient especially for an interview setting. My comments in the code are self explanatory. Im using a variable track to traverse through the list and checking for a null or head as the next. If i encounter any of them traversal ends and then individually i check for null or head condition and based on that i return the appropriate boolean value.
function SLLNode(elem) {
this.value=elem;
this.next=null;
}
var hasCycle=function(node){
var track=node;
//traverse thru list till next node is either null or back to first node
while(track.next!==null && track.next!==this.head){
track=track.next;
}
if(track.next === null){ //if next node null then no cycle
return false;
}
if(track.next===this.head){ //if next node head then there is cycle
return true;
}
}
var my_node1=new SLLNode(3);
var my_node2=new SLLNode(5);
var my_node3=new SLLNode(19);
//assigning head
var head=my_node1;
//connecting linked list
my_node1.next=my_node2;
my_node2.next=my_node3;
my_node3.next=my_node1; //cycle
console.log("Has cycle?: "+hasCycle(my_node1)); //outputs true as expected
var node1=new SLLNode(3);
var node2=new SLLNode(5);
var node3=new SLLNode(19);
//assigning head
var head1=node1;
node1.next=node2;
node2.next=node3;
console.log("Has cycle?: "+hasCycle(node1)); //outputs false as expected
JSON.stringify() can be used to detect cyclic linked lists. CircularDetector returns true if the linked list is cyclic.
function CircularDetector (head) {
try {
JSON.stringify(head);
return false;
} catch (e) {
return true;
}
}
You can read more on cycle detection at https://en.wikipedia.org/wiki/Cycle_detection but the main takeaway is that if you move one pointer twice as fast as another pointer then a loop would be identifiable as the fast pointer will eventually catch up with the other. Here's a possible solution in js.
function hasCycle(head) {
var slow, fast;
if(!head || !head.next) return false;
slow = head;
fast = head;
if(head.next === head) return true;
while(fast.next.next) {
slow = slow.next;
fast = fast.next.next;
if(slow === fast) return true;
}
return false;
}
Not a very efficient solution as I am using map but if you don't want to use two pointers this solution is easy to understand
// Preparation code:
class Node {
constructor(value) {
this.value = value;
this.next = null;
}
}
function hasCycle(head) {
let node = head;
let map={};
while(node){
if(map[node.value]){
//return node or true
return {"Found":node}
}
else{
map[node.value] = true;
}
node = node.next;
}
return "Not found";
}
const nodeA = new Node('A');
const nodeB = nodeA.next = new Node('B');
const nodeC = nodeB.next = new Node('C');
const nodeD = nodeC.next = new Node('D');
const nodeE = nodeD.next = new Node('E');
console.log(hasCycle(nodeA)); // => null
nodeE.next = nodeB;
console.log(hasCycle(nodeA))

Way to save console.count() as an integer?

I am trying to divide 1 by the console.count() every time it is used. However, this code does not work.
var counter = console.count();
console.log(1/counter);
Any suggestions on how I could do this? I tried doing parseInt but no luck.
Way to save console.count() as an integer?
No. console.count() does not return anything, it directly prints to the console, just like console.log().
Simple implementation of console.count:
var count = (function() {
var counter = {};
return function(v) {
return (counter[v] = (counter[v] || 0) + 1);
}
}());
console.log('foo', count('foo'));
console.log('foo', count('foo'));
console.log('bar', count('bar'));
Here is a script that intercepts messages sent to the console.
var counter = 0;
function takeOverConsole(){
var console = window.console
if (!console) return
function intercept(method){
var original = console[method]
console[method] = function(){
var message = Array.prototype.slice.apply(arguments).join(' ')
// do sneaky stuff
if (original.call){
// Do this for normal browsers
original.call(console, message)
}else{
// Do this for IE
original(message)
}
counter++;
}
}
var methods = ['log', 'warn', 'error', 'count']
for (var i = 0; i < methods.length; i++)
intercept(methods[i])
}
To take Felix King's answer a bit further. Here is a more accurate way to intercept and count anything being sent to the console.
You can customize the function a bit and add any methods you want to track and count.
All console methods
I talk about it more here

Javascript function that returns two different types of variables depending on input?

I'm trying to follow the rule and avoid repeating the same code.
I have this single function but depending on the input I want it to either return an array of objects or an object (not an array of just one object)
e.g.(the actual function is much longer and more elaborate than this one obviously, there are just the last few lines after a much longer calculation)
function (nameParameter, ageParameter, inputType)
{
if (inputType === "asObject")
{
var x = {};
x.name = nameParameter;
x.age = ageParameter;
return x;
}
else if (inputType === "asArray")
{
var y = [];
y.push(nameParameter);
y.push(ageParameter);
return y;
}
};
Is this possible and if so is it good practice? Is there some other way around it?
Otherwise I'll have to create two distinct function with almost the exact same code.
Don't do this. Implement one version and add a wrapper function that converts the the other format you may want. That way the caller always gets consistent behaviour, and theres still no code duplication.
function asObject(nameParameter, ageParameter)
{
//Lots of work here.
var x = {};
x.name = nameParameter;
x.age = ageParameter;
return x;
};
function asArray(nameParameter, ageParameter)
{
//Just defer to the other version and repack its response.
var o = asObject(nameParameter, ageParameter);
var y = [o.nameParameter,o.ageParameter ];
return y;
}
You can simplify your code by declaring the object and array with the values already set, but in my opinion if you have this strict type of coding it is not necessary to keep this function... Anyway, here is a simplified version:
function (nameParameter, ageParameter, inputType) {
var ret;
if (inputType === "asObject") {
ret = {
name: nameParameter,
age: ageParameter
};
} else if (inputType === "asArray") {
ret = [nameParameter, ageParameter];
}
return ret;
};
I left it without name and with a semicolon at the end because I guess it has been declared through a variable.
Yes; that will work fine.
Javascript is not strongly-typed; functions can return whatever they want, whenever they want.
if ( typeof inputType == 'object') {
//object part of code
} else {
//array part of code
}

Javascript conditional callbacks

I'm currently using javascript to do some experiments and although I'm not new to JS I have a doubt that I hope the good folks at SO will be able to help.
Basically I'm making a jsonp request to a webservice that returns me the amount/length on the reply (just counting objects).
Then I'm randomly selecting 9 of those objects to place in an array and here lies the problem. I would like to make sure that none of those 9 objects is repeated.
To achieve this I'm using the following code:
function randomizer() {
return Math.ceil(Math.random()*badges.length);
}
function dupsVerify(array, number) {
array.forEach(function () {
if(array === number) {
return true;
}
});
return false;
}
// Randomly choose 9 array indexes
var randomBadge = function () {
var selectedIndexes = new Array();
while(selectedIndexes.length < 9) {
var found = false;
var randomNumber = randomizer();
if(!dupsVerify(selectedIndexes, randomNumber)) {
selectedIndexes.push(randomNumber);
} else {
newRandom = randomizer();
dupsVerify(selectedIndexes, newRandom);
}
}
return selectedIndexes;
}
I've tried a couple different methods of doing this verification but I've been thinking if it wouldn't be possible to do the following:
Generate the random number and go through the array to verify if it already exists in the array. If it exists, generate another random number (randomize call) and verify again.. If it doesn't exist in the array, then push it to the "final" array.
How can I achieve this? Using callbacks?
Am I doing this right or should I chance the code? Is there a simpler way of doing this?
Best Regards,
This would get you the desired behavior:
function getRandomPositions(sourcearray, desiredcount){
var result = [];
while(result.lentgth < desiredcount){
var rnd = Math.ceil(Math.random()*sourcearray.length);
if (result.indexOf(rnd) == -1){
result.push(rnd);
}
}
return result;
}
Instead of generating X random numbers, just generate a random number, but don't add it if it already exists.
I ended up finding the best solution for this scenario by using the following code:
function randomizer() {
return Math.ceil(Math.random()*badges.length);
}
function dupsVerify(array, number) {
var result;
if(array.length === 0) {result = false;}
array.forEach(function (item) {
if(item === number) {
result = true;
} else {
result = false;
}
});
return result;
}
// Randomly choose 9 array indexes
function randomBadge() {
while(cards.length < 9) {
var randomNumber = randomizer();
if(!dupsVerify(cards, randomNumber)) {
cards.push(randomNumber);
} else {
randomBadge();
}
}
return cards;
}
This represents the same behavior (and a few minor code corrections) but ensures that I will never get an array with 2 repeated objects.

Categories

Resources