Insertion Sort Function Error - javascript

In order to do this, the insert function will need to make room for value by moving items that are greater than value to the right. It should start at rightIndex, and stop when it finds an item that is less than or equal to value, or when it reaches the beginning of the array. Once the function has made room for value, it can write value to the array.
var insert = function(array, rightIndex, value) {
var key = value;
for(var i = rightIndex; array[i] > value ; i = i - 1)
{
array[rightIndex + 1] = array[rightIndex];
}
array[i+1] = value;
};
Why My this function doesn`t work correctly after I input this array !
var array = [3, 5, 7, 11, 13, 2, 9, 6];
It Shows this result:
insert(array, 4, 2);
2,5,7,11,13,13,9,6

The line that shuffles items to the right needs editing
Change your line that currently reads:
array[rightIndex + 1] = array[rightIndex];
to read as follows:
array[i + 1] = array[i];
In your code as currently written, the rightIndex'th item is repeatedly being pasted into the rightIndex+1'th position. This is why you are getting two 13s in your result.
So your code is almost right already!
Explicitly check for the beginning of the array
You can change the for loop to ensure you never go left of the start of the array.
for(var i = rightIndex; i>=0 && array[i] > value ; i = i - 1)
Inserting the i>=0 && means that when i falls below 0, Javascript knows to end the loop. Otherwise it will attempt to read the element array[-1], which is undefined. Luckily the test will still work, because a comparison of any number (even negative) with "undefined", will be false. But it is much better style to explicitly test for this rather than rely on the quirk of the language. The reason is that if you were to apply the same algorithm in another language, the array[-1] might be an error.

inserting value into array works correctly with sorted array, in this case your array is not sorted.
var array = [3, 5, 7, 11, 13, 2, 9, 6];
you need to first sort the array, for that use this
var array = [3, 5, 7, 11, 13, 2, 9, 6];
array = arra.sort(function (a, b) { return a - b; });
array = array.sort((a, b) => a - b);
//outputs: 2, 3, 5, 6 , 7, 9, 11, 13
then you can insert into this array as sorted
For that you can try something like this
var array = [2, 3, 5, 6 , 7, 9, 11, 13];
var element = 2;
function insert(element, array) {
array.push(element);
array.sort(function(a, b) {
return a - b;
});
return array;
}
//outputs: 2, 2, 3, 5, 6 , 7, 9, 11, 13

Related

JavaScript. Filtering an array with the Splice() method [duplicate]

This question already has answers here:
Looping through array and removing items, without breaking for loop
(17 answers)
Closed last year.
I need to write a function
filterRangeInPlace(arr, a, b)
that takes an array and two numbers and deletes all elements from the array that are not within the range a to b. So the check looks like
a ≤ arr[i] ≤ b
I want to do it with the for loop and splice method. But can't figure out why the function keeps some elements outside of the range, in my case below it's number 3. This is not a home task or whatever, I'm just practicing array methods. Here's my code:
let myArr = [1, 3, 8, 3, 9, 5, 3, 4, 10, 7, 6, 1]
function filterRangeInPlace( arr, a, b ) {
for ( i = 0; i < arr.length; i++ ) {
if ( arr[i] < a || arr[i] > b ) {
arr.splice(i, 1)
}
}
}
filterRangeInPlace(myArr, 4, 9)
console.log(myArr) // [3, 8, 9, 5, 4, 7, 6]
I understand I messed with the index somewhere, but can't figure out where and how, as the rest works fine. Thanks!
You should start iterating from the end of the array if you are using splice here and go upto the first element as:
for (i = arr.length - 1; i >= 0; i--) {
Let say, you are removing the first element i.e. 1 at position 0 then after removing the array will be
[3, 8, 3, 9, 5, 3, 4, 10, 7, 6, 1]
and at that time the i increments and becomes 1, so now it will point to 8 as 1 index.
So using splice will skip some of the steps
let myArr = [1, 3, 8, 3, 9, 5, 3, 4, 10, 7, 6, 1];
function filterRangeInPlace(arr, a, b) {
for (i = arr.length - 1; i >= 0; i--) {
if (arr[i] < a || arr[i] > b) {
arr.splice(i, 1);
}
}
}
filterRangeInPlace(myArr, 4, 9);
console.log(myArr);
When you use splice, and you're still in the same loop, you skip some indexes (because splice deletes number of items, so the indexes are changed).
In your example, the 1, which is first, is deleted, so 3 becomes the first one, but then you skip to the second (i++ in the loop). You don't double check the same index.
I'd recommend using filter method to do that, or just putting i-- on the line after splice.

JavaScript: Rearrange an array in order – largest, smallest, 2nd largest, 2nd smallest, 3rd largest, 3rd smallest,

Given an array of integers, where the values should be sorted in the following order:
if we have an array
[1, -1, -3, 9, -2, -5, 4, 8,]
we must rearrange it this way: largest number, smallest number, 2nd largest number, 2nd smallest number, ...
[9, -5, 8, -3, 4, -2, 1, -1 ]
I get the first largest and smallest numbers, but can't figure out how to make it dynamic for all values in the array.
I know that I must take two variables, say firstSmallest and firstLargest and point them to the first and last index of the array respectively, run a loop, which I do already in the code below, and store value into new array by incrementing firstSmallest and decrementing firstLargest, but couldn't implement into code.
let unsortedArr = [1, 5, 8 , 7, 6, -1, -5, 4, 9, 5]
let output = [];
function meanderArray(unsorted){
let sorted = unsorted.sort((a, b) => a-b);
let firstSmallest = sorted[0];
let firstLargest = sorted[unsorted.length-1];
for(let i = 0; i <= sorted.length; i++){
//I should increment firstSmallest and decrement firstLargest numbers and store in output
}
return output;
}
meanderArray(unsortedArr);
console.log(output);
You could take a toggle object which takes the property of either the first item or last from an array and iterate until no more items are available.
function meanderArray([...array]) {
const
result = [],
toggle = { shift: 'pop', pop: 'shift' };
let fn = 'shift';
array.sort((a, b) => a - b);
while (array.length) result.push(array[fn = toggle[fn]]());
return result;
}
console.log(...meanderArray([1, 5, 8, 7, 6, -1, -5, 4, 9, 5]));
You can sort an array by descending, then logic is the following: take first from start and first from end, then second from start-second from end, etc.
let unsortedArr = [1, 5, 8 , 7, 6, -1, -5, 4, 9, 5]
let output = [];
function meanderArray(unsorted){
let sorted = unsorted.sort((a, b) => b-a);
let output = []
for(let i = 0; i < sorted.length/2; i++){
output.push(sorted[i])
if(i !== sorted.length - 1 - i){
output.push(sorted[sorted.length - 1 - i])
}
}
return output;
}
let result = meanderArray(unsortedArr);
console.log(result);
You can sort, then loop and extract the last number with pop() and extract the first number with shift().
let unsortedArr = [1, -1, -3, 9, -2, -5, 4, 8,]
let output = [];
function meanderArray(unsorted){
let sorted = unsorted.sort((a, b) => a - b);
for(let i = 0; i < unsortedArr.length + 2; i++){
output.push(sorted.pop());
output.push(sorted.shift());
}
console.log(output);
return output;
}
meanderArray(unsortedArr);
Fastest Meandering Array method among all solutions mentioned above.
According to the JSBench.me, this solution is the fastest and for your reference i have attached a screenshot below.
I got a different approach, but i found that was very close to one of above answers from elvira.genkel.
In my solution for Meandering Array, First I sorted the given array and then i tried to find the middle of the array. After that i divided sorted array in to two arrays, which are indices from 0 to middle index and other one is from middle index to full length of sorted array.
We need to make sure that first half of array's length is greater than the second array. Other wise when applying for() loop as next step newly created array will contains some undefined values. For avoiding this issue i have incremented first array length by one.
So, always it should be firstArr.length > secondArr.length.
And planned to create new array with values in meandering order. As next step I created for() loop and try to push values from beginning of the first array and from end of the second array. Make sure that dynamically created index of second array will receive only zero or positive index. Other wise you can find undefined values inside newly created Meandering Array.
Hope this solution will be helpful for everyone, who loves to do high performance coding :)
Your comments and suggestions are welcome.
const unsorted = [1, 5, 8, 7, 6, -1, -5, 4, 9, 5];
const sorted = unsorted.sort((a,b)=>a-b).reverse();
const half = Math.round(Math.floor(sorted.length/2)) + 1;
const leftArr = sorted.slice(0, half);
const rightArr = sorted.slice(half, sorted.length);
const newArr = [];
for(let i=0; i<leftArr.length; i++) {
newArr.push(leftArr[i]);
if (rightArr.length-1-i >= 0) {
newArr.push(rightArr[rightArr.length-1-i]);
}
}

each time printing result set in data of 3

I am trying to print the data in chunks of three.
so I thought I will iterate the array and each time I will take three elements and print it.
so I thought I will use slice but not working
but I am not sure how to proceed.
providing my code snippet below.
I debugged but still not sure how to proceed.
let array = [1, 4, 5, 6, 7, 78, 3, 999, 544, 3, 3, 32233, 223, ];
array.map(search => {
// return {
console.log("chunks of data--->", search.slice(3));
// };
});
I think you only want to print everything once, if that is the case you have to use %3 to do something every 3x time - in this case logging the current and past 2 elements. at the end you also have to print the left over elements in case your number of elements isnt a multiple of 3.
// a forEach loop takes an array and calls a function on each element in it
array.forEach((el, index, arr) => {
// is this element a multiple of 3?
if ((index + 1) % 3 === 0) {
// If so, log it, as well as the 2 preceding elements
console.log(arr[index-2], arr[index-1], el)
// Otherwise, is this element the last one in the array, meaning there
// wont be another tuple logging this element
} else if (index === arr.length - 1) {
// If so, how many elements are left, one or two?
// log this many last elements to the console
// I used a ternary in this case it is basically a shorthand if
// [expression] ? [if true] : [if false]
arr.length % 3 === 1 ? console.log(arr[index]) : console.log(arr[index - 1], arr[index])
}
})
You use slice with an array, not a number, to get chunks of 3 (or any arbitrary n), use this:
var array = [1, 4, 5, 6, 7, 78, 3, 999, 544, 3, 3, 32233, 223, ];
var n = 3;
var chunk;
for (var i = 0; i < array.length; i += n) {
chunk = array.slice(i, i + n);
console.log(chunk);
}
You must use index for this
let array = [1, 4, 5, 6, 7, 78, 3, 999, 544, 3, 3, 32233, 223, ];
array.map((search,index) => {
if(index%3!==0){
return;
}
let limit = index+3;
// this part need when index almost at the end of the array
if((index+3)>=array.length){
limit =array.length;
}
console.log("chunks of data--->", array.slice(index,limit));
// };
});

Is it possible to use array.splice(argument[i], x) to edit an array for variables that meet a condition?

Key Question
-How do you use splice(argument[i], x)? Can it be used this way or am I only allowed to use numbers? ie (1, 2), (3, 0)
-I'm a little unsure of when element[i] can be used when an array is declared. So it can be used for both for loops and while loops when setting conditions? Can it be used as an argument or parameter in functions or additional methods besides splice?
What I want to do
-Write a function called "isEven".
-Given an array of numbers, "isEven" returns a new array.
-Only even numbers are outputted from the input array.
ex.
var output = isEven([1, 4, 5, 6, 10, 13]);
console.log(output); // --> [4, 6, 10]
Approach
-declare var digits to "catch" the array input.
-declare var NewArray for return of output array,
-use if condition to go through var digits and splice the variable at any given index.
-declare NewArray to the newly spliced array
function isEven(num) {
var digits = num;
var newArray = [];
digits.forEach(function(num) {
if (num[i] % 2 > 0) {
newArray = digits.splice(num[i], 1);
}
}) return newArray;
}
var ledoit = isEven([1, 4, 6]);
console.log(ledoit);
Try this:
function isEven(myArray) {
return myArray.filter(item => {
return Number.isInteger(item / 2)
})
}
Then isEven([1, 4, 5, 6, 10, 13]) will output [4,6,10]
You want to use the % operator:
var nums = [1, 4, 5, 6, 10, 13];
function getEvens(array){
for(var i=0,n,a=[],l=array.length; i<l; i++){
n = array[i];
if(n % 2 === 0)a.push(n);
}
return a;
}
console.log(getEvens(nums));
Albeit, not backward compatible, you could also do:
var nums = [1, 4, 5, 6, 10, 13];
function getEvens(array){
return array.filter(n => (n % 2 === 0));
}
console.log(getEvens(nums));

Compare an unspecified number of arrays for common values in javascript

I would like to know how to compare two or more -- potentially unlimited -- arrays for common values and push these values into a new array efficiently. Below I have a function that will accept unlimited arguments, but I am uncertain if this is a good place to begin. PHP appears to have a method that can do what I want called array_intersect. Does javascript offer something similar?
Note: I have found examples of how this can be done with two or so arrays, but I have not found examples of how such approaches might be applied to an unspecified number of arrays as of yet. Therefore I do not see this as a duplicate question.
To further clarify, the arrays might be filled with anything. Letters, numbers, symbols, words, you name it, it might be there.
var sampleOne = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
var sampleTwo = [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18];
function FindDirectRelation() {
for(var i = 0; i < arguments.length; ++i) {
console.log(arguments[i]);
};
};
var directRelation = FindDirectRelation(sampleOne, sampleTwo);
I am still a coding novice, so please ensure that everything is explained in a way that is simple enough for me to understand.
using an existing intersect that works with 2 arrays, we can chain together a common sub-set using the built-in reduce() method on an array of arrays that need intersected:
function intersect(a, b) {
var aa = {};
a.forEach(function(v) { aa[v]=1; });
return b.filter(function(v) { return v in aa; });
}
var r1=[1,2,3],
r2=[1,3,4,5],
r3=[5,1,3];
alert([r1, r2, r3].reduce(intersect)) // shows: 1,3
if you define "intersect" as just being in more than one array (not every), then it's more complex...
Check to make sure the elements in the first array are also in the remaining arrays:
function multi_intersect(a) {
var other_arrays = Array.prototype.slice.call(arguments, 1);
return a . filter(function(elt) {
return other_arrays.every(function(an) {
return an.indexOf(elt) !== -1;
});
});
}
Try using Array.prototype.filter() , Array.prototype.indexOf()
var res = sampleOne.filter(function(val) {return sampleTwo.indexOf(val) !== -1})
var sampleOne = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
var sampleTwo = [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18];
var arr = ["a", "b", "c"];
var arr1 = ["c", "d", "e"];
var arr2 = [2, 7];
function samples() {
var args = Array.prototype.slice.call(arguments);
var res = [];
for (var i = 0, curr, next; i < args.length; i++) {
if (args[i + 1]) {
// set `curr` to array `i`
curr = args[i];
// set `next` to array `i + 1` if it exists
next = args[i + 1]
} else {
// if at last index, set `curr` to `args` : input arrays
// flattened to single array , with element at `i` removed
curr = [].concat.apply([], args.slice(0, args.length - 1));
console.log(curr)
// set next to current index
next = args[i];
};
next = next.filter(function(val) {
return curr.indexOf(val) !== -1
// filter duplicate entries at `res`
&& res.indexOf(val) === -1
});
res = res.concat.apply(res, next);
};
return res
}
var sample = samples(sampleOne, sampleTwo, arr, arr1, arr2);
console.log(sample); // [5, 6, 7, 8, 9, 10, 11, 12, "c", 2]

Categories