Clear an array with empty elements - javascript

I wrote the object as the second element in the array, and then sorted it. As a result, we got an array of one object and two empty values, which are not indicated in any way.
It looks like this: [{...}, empty × 2]
How can I clean it?
My code
for (i = 0; i < data.Levels.length; i++) {
$.each(data.Ranges, function() {
for (var property in this) {
if (this[property][i] != 0) {
isNullable = false;
break;
}
}
if (!isNullable) {
return false;
}
});
if (!isNullable) {
levels[i] = { //Writing object
Level: data.Levels[i],
Position: i
};
}
}
levels.sort(function (a, b) {
if (a.Level < b.Level) {
return -1;
}
if (a.Level > b.Level) {
return 1;
}
return 0;
});

Add new elements to the end of the array with push, avoiding creating a sparse array entirely:
for (i = 0; i < data.Levels.length; i++) {
$.each(data.Ranges, function() {
for (var property in this) {
if (this[property][i] != 0) {
isNullable = false;
break;
}
}
if (!isNullable) {
return false;
}
});
if (!isNullable) {
levels.push({ //Writing object
Level: data.Levels[i],
Position: i
});
}
}

Related

update priority of queue in javascript

in hasValue class, why return is not working? when i try with console.log and alert, it worked.
want to implement function like priorityQueue.changePriority("Sheru", 1); changePriority class is not working.
commented code is code i tried to implement the changes i.e. i want to change the priority of existing item present in queue. Could anyone please help?
class QElement {
constructor(element, priority) {
this.element = element;
this.priority = priority;
}
}
class PriorityQueue {
constructor() {
this.items = [];
}
isEmpty() {
return this.items.length == 0;
}
add(element, priority) {
var qElement = new QElement(element, priority);
var contain = false;
for (var i = 0; i < this.items.length; i++) {
if (this.items[i].priority > qElement.priority) {
this.items.splice(i, 0, qElement);
contain = true;
break;
}
}
if (!contain) {
this.items.push(qElement);
}
}
peek() {
if (this.isEmpty())
return "No elements in Queue";
return this.items[0];
}
poll() {
if (this.isEmpty())
return "Underflow";
return this.items.shift();
}
/*changePriority(firstTerm, secondTerm)
{
let xxx = new QElement(firstTerm, secondTerm);
for (let i = 0; i < this.items.length; i++){
if (this.items[i].element === firstTerm){
this.items[i].priority = secondTerm;
this.items.splice(i, 0, xxx);
}
}
this.items.push(xxx);
}*/
hasValue(args) {
let status = false;
for (let i = 0; i < this.items.length; i++) {
if (this.items[i].element === args) {
status = true;
}
}
console.log(status);
}
size() {
if (this.isEmpty())
return "Underflow";
return this.items.length;
}
printPQueue() {
var str = "";
for (var i = 0; i < this.items.length; i++)
str += this.items[i].element + " ";
return str;
}
}
var priorityQueue = new PriorityQueue();
console.log(priorityQueue.isEmpty());
console.log(priorityQueue.peek());
priorityQueue.add("Sumit", 2);
priorityQueue.add("Gourav", 1);
priorityQueue.add("Piyush", 1);
priorityQueue.add("Sunny", 2);
priorityQueue.add("Sheru", 3);
console.log(priorityQueue.printPQueue());
console.log(priorityQueue.peek().element);
console.log(priorityQueue.poll().element);
priorityQueue.add("Sunil", 2);
console.log(priorityQueue.size());
priorityQueue.hasValue('Sumit');
console.log(priorityQueue.printPQueue());
priorityQueue.changePriority("Sheru", 1);
console.log(priorityQueue.printPQueue());
You missing return keyword. This just works:
hasValue(args) {
for (let i = 0; i < this.items.length; i++) {
if (this.items[i].element === args) {
return true;
}
}
return false;
}
I did not understand the idea how your changePriority function should work. Just find the element and move it up or down based on priority change:
swap(a, b) {
let tmp = this.items[a];
this.items[a] = this.items[b];
this.items[b] = tmp;
}
changePriority(firstTerm, secondTerm) {
let i = 0;
while (i < this.items.length) {
if (this.items[i].element === firstTerm) {
if (secondTerm < this.items[i].priority) {
// move up
this.items[i].priority = secondTerm;
while (i > 0 && this.items[i - 1].priority > secondTerm) {
this.swap(i - 1, i);
i--;
}
} else if (secondTerm > this.items[i].priority) {
// move down
this.items[i].priority = secondTerm;
while (i < this.items.length - 1 && this.items[i + 1].priority < secondTerm) {
this.swap(i + 1, i);
i++;
}
}
break;
}
i++;
}
}

Returning Object Property in Javascript Undefined

I have this code:
function Tree() {
this.capacity = 1;
this.contents = 0;
this.children = [];
this.divided = false;
this.pour = function(amount) {
this.contents += amount;
if (this.contents <= 1) {
return;
}
if (!this.divided) {
this.divide();
}
amount = this.contents - 1;
this.contents = 1;
for (let child in this.children) {
this.children[child].pour(amount * .5);
}
}
this.divide = function() {
this.children = new Array(2).fill(0).map(x => new Tree());
this.divided = true;
return;
}
this.getContents = function(row, currentRow) {
if (currentRow === undefined) {
currentRow = 0;
}
if (row === currentRow) {
console.log('Contents:', this.contents)
return this.contents;
}
if (this.divided) {
console.log(row, currentRow)
currentRow++;
this.children[0].getContents(row, currentRow);
} else {
return;
}
}
}
Upon creating a tree, pouring into it, and getting its contents using this:
let tree = new Tree();
tree.pour(10);
tree.getContents(1);
It should return 1 because the second rows contents is 1. It logs 1 in the console but does not return the correct value. I am curious to what is going wrong.
Edit: I looked at switching it to a class and it did not solve the problem:
class Tree {
constructor() {
this.capacity = 1;
this.contents = 0;
this.children = [];
this.divided = false;
}
pour(amount) {
this.contents += amount;
if (this.contents <= 1) {
return;
}
if (!this.divided) {
this.divide();
}
amount = this.contents - 1;
this.contents = 1;
for (let child in this.children) {
this.children[child].pour(amount * .5);
}
}
divide() {
this.children = new Array(2).fill(0).map(x => new Tree());
this.divided = true;
return;
}
getContents(row, currentRow) {
if (currentRow === undefined) {
currentRow = 0;
}
if (row === currentRow) {
console.log('Contents:', this.contents)
return this.contents;
}
if (this.divided) {
console.log(row, currentRow)
currentRow++;
this.children[0].getContents(row, currentRow);
} else {
return;
}
}
}
The console.log you are seeing is the result of this call:
if (this.divided) {
console.log(row, currentRow)
currentRow++;
this.children[0].getContents(row, currentRow); //<-- here
// this is calling getContents() but ignores the return value
but in that case you don't actually return anything, so the inner console.log() fires but the return value is undefined.
I'm not really sure what the code is supposed to do, but returning a value when that condition is met results in a return value for the whole function:
if (this.divided) {
console.log(row, currentRow)
currentRow++;
return this.children[0].getContents(row, currentRow);
It logs 1 to the console because you call
tree.pour(10)
Current row is undefined because you do not pass it in the argument
if (currentRow === undefined) {
currentRow = 0;
}
if (row === currentRow) {
console.log('Contents:->', this.contents)
return this.contents;
}
So it mean currentRow is 0 and row(1) is not equals to currentRow (0) which is why it returns undefined.
} else {
return;
}

Flatten Nested Array Without Using Flatten Function

I'm currently stuck on a problem. I'm trying to make [[1,2,[3]],4] -> [1,2,3,4] but cannot get it to work. The output I keep getting is: 1,2,3,4
1,2,3
3
3
3
3..........3
function flattenArray(input) {
var result = [];
console.log(input.toString());
for(i = 0; i < input.length; i++) {
if(input[i].constructor === Array) {
result.push(flattenArray(input[i]));
} else {
result.push(input[i]);
}
}
return result;
}
console.log(flattenArray([[1,2,[3]],4]));
I have this in my common.js file. I use it all the time.
Array.prototype.flatten = function () {
var ret = [];
for (var i = 0; i < this.length; i++) {
if (Array.isArray(this[i])) {
ret = ret.concat(this[i].flatten());
} else {
ret.push(this[i]);
}
}
return ret;
};
Here it is as a function:
function flattenArray(input) {
console.log(input.toString());
var ret = [];
for (var i = 0; i < input.length; i++) {
if (Array.isArray(input[i])) {
ret = ret.concat(flattenArray(input[i]));
} else {
ret.push(input[i]);
}
}
return ret;
}

Displaying all the items in an array using jquery and json

I am trying to get all the items in an array to show using json and jquery from the song of ice and fire api. I can only get one item to show from each of the arrays.
Here is the codepen: https://codepen.io/frederickalcantara/pen/aWeXOz
var data;
$.getJSON(characters[i], function(json) {
data = json;
var alliance = $('#alliance');
for (var i = 0; i < data.allegiances.length; i++) {
if (i === data.allegiances.length - 1) {
$.getJSON(data.allegiances[i], function(json1) {
alliance.html(json1.name);
});
} else {
$.getJSON(data.allegiances[i], function(json1) {
alliance.html(json1.name + ', ');
});
}
}
const title = $('#title');
if (data.titles.length === "") {
return 'N/A';
} else {
for (i = 0; i < data.titles.length; i++) {
if (i === data.titles.length - 1) {
title.html(data.titles[i]);
} else {
title.html(data.titles[i]) + ', ';
}
}
const tv = $('#seasons');
for (var i = 0; i < data.tvSeries.length; i++) {
if (i === data.tvSeries.length - 1) {
tv.html(data.tvSeries[i]);
} else {
tv.html(data.tvSeries[i] + ', ');
}
}
const actor = $('#actors')
if (json.playedBy === "") {
return 'N/A';
} else {
actor.html(json.playedBy);
}
});
The main problem is your loop. You keep replacing the value in the html element until the last value in the array. You can simplify this code like this:
title.html(data.titles.join(','));
which replaces all of this:
for (i = 0; i < data.titles.length; i++) {
if (i === data.titles.length - 1) {
title.html(data.titles[i]);
} else {
title.html(data.titles[i]) + ', ';
}
}
Update: Handling the allegiances.
Using a Promise here is important because you are making a number of AJAX calls and you need to be sure that they are resolved before attempting to display them. You can replace the entire for loop for the allegiances like this:
Promise.all(data.allegiances.map(function(ally){
return new Promise(function(resolve, reject){
$.getJSON(ally, function(json) {
resolve(json.name);
});
});
}))
.then(function(allies){
alliance.html(allies.join(', '));
});

I can't figure out why it's saying that the matcher function is undefined.

This code is designed to identify an array of anagrams for a string given an array of possible anagrams.
var anagram = function(input) {
return input.toLowerCase();
}
I'm adding the matcher function here to the String prototype.
String.prototype.matcher = function(remainingLetters) {
var clone = this.split("");
for (var i = 0; i < clone.length; i++) {
if (clone[i].indexOf(remainingLetters) > -1) {
remainingLetters.splice(clone[i].indexOf(remainingLetters, 1));
clone.splice(i, 1);
}
}
if (remainingLetters.length == 0 && clone.length == 0) {
return true;
}
else {
return false;
}
}
a
String.prototype.matches = function(matchWordArray) {
var result = [];
for (var i = 0; matchWordArray.length; i++) {
var remainingLetters = this.split("");
if (matchWordArray[i].matcher(remainingLetters)) {
result.push(arrayToMatch[i]);
}
}
return result;
}
var a = anagram("test");
a.matches(["stet", "blah", "1"]);
module.exports = anagram;
Should probably be:
for (var i = 0; i < matchWordArray.length; i++) {
The original statement:
for (var i = 0; matchWordArray.length; i++) {
...would result in an infinite loop because matchWordArray.length is always truthy (3) in your test.

Categories

Resources