I have a function urlScores which return an array of object in the form
[{"url":"facebook","score":2},{"url":"reddit","score":1},{"url":"stackoverflow","score":3}]
I am asked to sort this array in regards to its score using bubble sort.
What I have tried doing is creating a bubble sorting function that takes the object returned from urlScores and sorts it.
function sort(object)
{
for(var i= 0; i < object.length; i++){
if (object[i].score > object[i+1].score) {
var temp = object[i]
object[i]=object[i+1]
object[i+1]=temp
}
}
}
And the function that should be called for sorting the array looks like:
function rankedScores(web,pattern)
{
return (sort(urlScores(web,pattern)))
}
This doesn't seem to be working, I am faced with TypeError: object[(i + 1)] is undefined
Any help is appreciated
I have corrected your sort function.
function sort(a) {
for (var i = 0; i < a.length - 1; i++) {
if (a[i].score > a[i + 1].score) {
var temp = a[i]
a[i] = a[i + 1]
a[i + 1] = temp
}
}
return a;
}
Here is an example
var arr= '[{"url":"facebook","score":2},{"url":"reddit","score":1},{"url":"stackoverflow","score":3}]';
console.log(sort(arr));
var a = [{"url":"facebook","score":2},{"url":"reddit","score":1},{"url":"stackoverflow","score":3}];
function bubbleSort(a)
{
var swapped;
do {
swapped = false;
for (var i=0; i < a.length-1; i++) {
if (a[i].score > a[i+1].score) {
var temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
swapped = true;
}
}
} while (swapped);
}
bubbleSort(a);
console.log(a);
Related
I am using javascript to display in a web page the number list at the end of each iteration in the Bubble Sorting method. The function seems like failed to sort, and I couldn't figure it why.
I am assuming the mistake I made is around the loop area.
<!DOCTYPE html>
<html>
<head>
<title>Bubble Sort</title>
<script type="text/javascript">
var array = new Array();
function pushArray(){
array.push((document.getElementById("elem").value));
document.getElementById("elem").value = '';
}
function isNumber(evt) {
evt = (evt) ? evt : window.event;
var charCode = (evt.which) ? evt.which : evt.keyCode;
if (charCode > 31 && (charCode < 48 || charCode > 57)) {
return false;
}
return true;
}
var count = 1
function myFunction() {
document.write("Array you entered was "+ array);
var arrayLength = array.length;
var i;
var j;
var k;
for(i=0;i<arrayLength;i++)
{
for(j=i+1;j<arrayLength;j++)
{
if(array[i]<array[j])
{
k=array[i];
array[i]=array[j];
array[j]=k;
}
document.write("<br/><br/>"+ count+"th iteration produced : " + array);
count = count + 1;
}
}
document.write("<br/><br/>After bubble sort in desending order " + array);
}
</script>
</head>
<body data-gr-c-s-loaded="true">
Enter the element here: <input type="text" id="elem" onkeypress="return isNumber(event)">
<br>
<button onclick="pushArray()">Add this element</button>
<p>Click the button to sort the array.</p>
<button onclick="myFunction()">Try it</button>
</body></html>
I found the error:
You are taking the values and placing within the array, creating an array with only one element. ex: array[0] -> 132423434344 and not array[0] -> 1, array[1] -> 3...
array.push((document.getElementById("elem").value));
Use the code below
function pushArray(){
array = document.getElementById("elem").value.split("");
document.getElementById("elem").value = "";
}
My bubble sort function:
function bubbleSort() {
document.write("Array you entered was " + array);
var arrayLength = array.length;
var i; var j; var temp; var count = 0;
for(i = 0; i < arrayLength; i++) {
for(j = 0; j < arrayLength - 1; j++) {
if(array[j] < array[j + 1]) {
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
document.write("<br/><br/>After bubble sort in desending order " + array);
}
function bubblesort () {
document.write("Array you entered was "+ array);
var arrayLength = array.length;
var i;
var j;
var k;
for (i=0; i < arrayLength; i++) {
for (j=0; j < arrayLength-1; j++) {
if (array[j] < array[j+1]) {
k = array[j];
array[j] = array[j+1];
array[j+1] = k;
}
}
}
document.write("<br/><br/>"+ count+"th iteration produced : " + array);
}
The following Bubble Sort has time complexity of n in best case and n^2 in worst case.
function bubbleSort(arr){
console.log("Input Array");
console.log(arr);
let i = 0
let temp;
let notSorted;
do {
notSorted = false;
for (let j = 0; j < arr.length-i; j++) {
if (arr[j] > arr[j+1]) {
notSorted = true;
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
console.log(arr[j],"swapped with",arr[j+1])
console.log(arr);
} else {
console.log("SKIP");
}
console.log(j, arr.length-i);
}
i++;
} while (notSorted)
console.log("Sorted using Bubble Sort");
return arr;
}
// console.log(bubbleSort([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20])); // uncomment to run and see how efficient this algorithm is when array is sorted
console.log(bubbleSort([5,8,18,4,19,13,1,3,2,20,17,15,16,9,10,11,14,12,6,7]));
Bubble Sort can be carried out recursively as follows:
const recursiveBubbleSort = function (a, p = a.length-1) {
if (p < 1) {
return a;
}
for (let i = 0; i < p; i++) {
if (a[i] > a[i+1]) {
[a[i], a[i+1]] = [a[i+1], a[i]];
}
}
return recursiveBubbleSort(a, p-1);
}
console.log(recursiveBubbleSort([2,1,4,7,3,9,5,6,8]));
Bubble Sort Solution With Javascript like this :
bubbleSort = (array) => {
let swaps = 0;
let temp;
for(let i=0 ; i <array.length;i++){
for(let j=0; j< array.length-1;j++){
if (array[j] > array[j + 1]) {
temp = array[j+1];
array[j+1] = array[j];
array[j] = temp;
swaps++;
}
}
}
console.log("Array is sorted in", swaps, "swaps.");
console.log("First Element:", array[0]);
console.log("Last Element:", array[array.length-1]);
}
I am trying to reverse a list of numbers however I am getting an output of undefined.
I am using closure to do it
here is my code
function reverseANumber(aList) {
function reverse() {
var newList = [];
var j=0;
for(var i = aList.length - 1; i >= 0; i--)
{
newList[j] = aList[i];
j++;
}
return newList
}
reverse(aList);
}
aList=[3,2,3,1];
console.log(reverseANumber(aList));
I am getting undefined as output
I am expecting 1 3 2 3 as output
What is wrong with my code ?
Simple
function reverseMe (list){
return list.reverse();
};
reverseMe([1,3,2,3]); // returns 3,2,3,1
Do not reinvent the wheel :)
Use Reverse
var aList=[3,2,3,1];
aList.reverse();
console.log(aList)
Outputs:
[1, 3, 2, 3]
CODEPEN DEMO
You forgot to add a return statement before the reverse(aList) call:
function reverseANumber(aList) {
function reverse() {
var newList = [];
var j = 0;
for(var i = aList.length; i >= 0; i--) {
newList[j] = aList[i];
j++;
}
return newList;
}
return reverse(aList);
}
aList = [3,2,3,1];
console.log(reverseANumber(aList));
You just declared a function inside of a function, which won't work.
Try this:
function reverseANumber(aList) {
var newList = [];
var j=0;
for(var i = aList.length - 1; i >= 0; i--)
{
newList[j] = aList[i];
j++;
}
return newList;
}
reverse(aList);
}
aList=[3,2,3,1];
console.log(reverseANumber(aList));
function reverseANumber(aList) {
let lastIndex = aList.length - 1;
let result = [];
function reverse(aList, lastIndex) {
if (lastIndex === -1) {
return;
}
result.push(aList[lastIndex])
reverse(aList, lastIndex - 1);
}
reverse(aList, lastIndex);
return result;
}
Can anyone tell me why all the object.num's print as 1? This is driving me mad. Somehow after the for loop the values of the object.num = 1 no matter what, even though they are never set to 1. Please copy the entire segment to debug.
<script type="text/javascript">
window.addEventListener("load", main, false);
const n = 4;
function main()
{
var belt = new Array(4*n);
initArr(belt);
printIt(belt);
populateArr(belt);
printIt(belt);
reorder(belt);
printIt(belt);
}
function populateArr(arr)
{
var a = {name:"a", num:0};
var b = {name:"b", num:0};
var end = arr.length;
var i = end-1;
for(var temp = n; temp > 0; temp--)
{
a.num = temp;
arr[i] = a;
i-=2;
}
i = end-2;
for(var temp = n; temp > 0; temp--)
{
b.num = temp;
arr[i] = b;
i-=2;
}
return arr;
}
function printIt(arr)
{
var tempArr = new Array(arr.length);
for(var i=0; i < arr.length; i++)
{
tempArr[i] = arr[i].name + arr[i].num;
}
console.log(tempArr);
}
function initArr(arr)
{
var nothing = {name:null, num:0};
for(var i=0; i<arr.length; i++)
{
arr[i] = nothing;
}
return arr;
}
function reorder(arr)
{
var nothing = {name:null, num:0};
var counter = 0;
var aIndex = 0;
var bIndex = null;
for(var i=0; i < arr.length; i++)
{
if(arr[i].name === "b" && bIndex === null)//first b doesn't get moved
{
bIndex = i+1;
}
else if(arr[i].name === "a")
{
arr[aIndex] = arr[i];
arr[i] = nothing;
counter++;
aIndex++;
}
else if(arr[i].name ==="b")
{
arr[bIndex] = arr[i];
arr[i] = nothing;
counter++;
bIndex++;
}
}
console.log("count: " + counter);
console.log("n: " + n);
return arr;
}
</script>
Somehow after the for loop the values of the object.num = 1 no matter what, even though they are never set to 1.
Yes "they" are - "they're" set to 1 in the last iteration of this loop:
for(var temp = n; temp > 0; temp--)
{
a.num = temp;
arr[i] = a;
i-=2;
}
The last iteration of that loop is when temp is 1.
Now, you've only actually got one object - and you're setting every element of the array to be a reference to that object. That's why all the values in the array look the same. If you want to create a different object each time, you should use:
for(var temp = n; temp > 0; temp--)
{
arr[i] = { name: "a", num: temp };
i -= 2;
}
If I have two arrays as parameters how can I find the starting index where the second parameter occurs as a sub-array in the array given as the first parameter.
E.g.: [5,9,3,6,8], [3,6] should return 2.
Is there a function in JavaScript for this, or does it just loop through both of them and compare?
findArrayInArray = function(a, b) {
var ai = a.length
, bi = b.length;
for(var i=0; i<ai; i++) {
if (a[i] === b[0]) {
if(bi === 1) return i;
for(var x=1; x<bi; x++) {
if(a[i+x] === b[x]) {
if(x === bi-1) return i;
} else {
break;
}
}
}
}
}
var arr1 = [5,9,3,6,8];
var arr2 = [3,6];
console.log(findArrayInArray(arr1,arr2)); // 2
http://jsfiddle.net/ymC8y/3/
In direct answer to your question, there is no built in function in JS to look in an array for a sub-array.
You will have to do some sort of brute force looping search like this or use some external library function that already has array comparison logic. Here's what a brute force solution in plain JS looks like:
function findSubArrayIndex(master, sub) {
for (var m = 0; m < master.length - sub.length + 1; m++) {
for (var s = 0; s < sub.length; s++) {
if (master[m + s] !== sub[s]) {
break;
} else if (s === sub.length - 1) {
return m;
}
}
}
return -1;
}
Working demo: http://jsfiddle.net/jfriend00/mt8WG/
FYI, here's a somewhat performance optimized version of this function:
function findSubArrayIndex(master, sub) {
var subLen = sub.length, subFirst, m, mlen;
if (subLen > 1) {
subFirst = sub[0];
for (m = 0, mlen = master.length - subLen + 1; m < mlen; m++) {
if (master[m] === subFirst) {
for (var s = 1; s < subLen; s++) {
if (master[m + s] !== sub[s]) {
break;
} else if (s === subLen - 1) {
return m;
}
}
}
}
} else if (subLen === 1) {
subFirst = sub[0];
for (m = 0, mlen = master.length; m < mlen; m++) {
if (master[m] === subFirst) {
return m;
}
}
}
return -1;
}
Working demo: http://jsfiddle.net/jfriend00/CGPtX/
function index (a, b) {
var as = new String(a),
bs = new String(b),
matchIndex = as.indexOf(bs);
if (matchIndex === -1) {
return -1;
} else if (matchIndex === 0) {
return 0;
}
return as.substring(0, matchIndex + 1).match(/,/g).length;
}
console.log(index([5,9,3,6,8], [3, 6]));
Try this - You loop through both arrays and compare each element:
var arr1 = [5,9,3,6,8];
var arr2 = [3,6];
findArrayInArray = function(arr1, arr2) {
for(var i=0; i<arr1.length; i++) {
for(var j=0; j<arr2.length; j++){
if(arr1[i] === arr2[j]){
return i;
}
}
}
return false;
}
findArrayInArray(arr1, arr2);
I have a SummaryData array as shown
var summaryData = [[0,100.34],[1,102.31],[2,131.08],[3,147.94],[4,172.55],[5,181.05],[6,180.08]];
My question is:
Is it possible to find out what the position of a value is?
(For example, how can I know where 147.94 is?) (I am expecting "3")
Update:
A more prototype-y way:
var result = summaryData.detect(function(item) { return item[1] === 147.94; });
alert(result[0]);
Or:
function getKey(arr, value) {
var key = null,
item;
for (var i = 0; i < arr.length && !key; i++) {
item = arr[i];
if (item[1] === value) {
key = i;
}
}
return key;
}
Usage:
var n = getKey(summaryData, 147.94); // returns 3.
At the risk of doing your homework for you...
var summaryData = [[0,100.34],[1,102.31],[2,131.08],[3,147.94],[4,172.55],[5,181.05],[6,180.08]];
function findPosition(value, dataArray) {
var a;
for (var i=0, iLen=dataArray.length; i<iLen; i++) {
a = dataArray[i];
for (var j=0, jLen=a.length; j<jLen; j++){
if (value == a[j]) {
return i + ',' + j;
}
}
}
}
alert(findPosition(131.08, summaryData)); // 2,1
The above returns the position of the first match.
Edit
I see now that you don't need to iterate over the second array, just look at the second value, so:
function findPosition(value, dataArray) {
var a;
for (var i=0, iLen=dataArray.length; i<iLen; i++) {
a = dataArray[i];
if (value == a[1]) {
return a[0];
}
}
}
alert(findPosition(131.08, summaryData)); //2
Or if the data format is always as specified and there may be thousands of values, then it may be much faster to do:
function findPosition(value, dataArray) {
var re = new RegExp('[^,],' + value);
var m = dataArray.join().match(re);
return m && m[0].replace(/,.*/,'');
// Or
// return m && m[0].split(',')[0];
}
function getPosition(candidate) {
var i = summaryData.length;
while (i) {
i -= 1;
if (summaryData[i][1] === candidate) {
return summaryData[i][0];
}
}
}