Inserting (splicing?) an Array into another Array without apply - javascript

Let's say we have two Arrays in JavaScript, [3,4,7] and [5,6].
Without sorting or using .apply, what is the best way to insert [5,6] into [3,4,7] at index 2 in order to achieve the resulting Array: [3,4,5,6,7]?

Don't know how you're defining "best way", but you can do this:
a.slice(0,2).concat(b,a.slice(2));
Unless you're saying you actually want to mutate the a Array, in which case you could do this:
var c = a.splice(2);
for (var i = 0; i < b.length + c.length; i++) {
a.push(i < b.length ? b[i] : c[i-b.length]);
}
This behavior of .splice() to split the Array in two parts may have issues in older IE that would need to be patched.
Or this would probably be better:
var c = b.concat(a.splice(2));
for (var i = 0; i < c.length; i++) {
a.push(c[i]);
}
Same caveat about .splice().

function splice(arrayOne, arrayTwo, index) {
var result = [];
for (var i = 0; i < arrayOne.length; i++) {
if (i == index) {
result = result.concat(arrayTwo);
}
result.push(arrayOne[i]);
}
return result;
}

Not really sure why you don't want to use the native methods, but here's a fairly naive solution with just loops:
function doInsert(index, items, arr) {
var insertLen = items.length,
current;
for (i = 0; i < insertLen; ++i) {
current = i + index;
arr[current + insertLen - 1] = arr[current];
arr[current] = items[i];
}
}
var arr = [3, 4, 7];
doInsert(2, [5, 6], arr);
console.log(arr);

Related

javascript reverse an array without using reverse()

I want to reverse an array without using reverse() function like this:
function reverse(array){
var output = [];
for (var i = 0; i<= array.length; i++){
output.push(array.pop());
}
return output;
}
console.log(reverse([1,2,3,4,5,6,7]));
However, the it shows [7, 6, 5, 4] Can someone tell me, why my reverse function is wrong? Thanks in advance!
array.pop() removes the popped element from the array, reducing its size by one. Once you're at i === 4, your break condition no longer evaluates to true and the loop ends.
One possible solution:
function reverse(array) {
var output = [];
while (array.length) {
output.push(array.pop());
}
return output;
}
console.log(reverse([1, 2, 3, 4, 5, 6, 7]));
You can make use of Array.prototype.reduceright and reverse it
check the following snippet
var arr = ([1, 2, 3, 4, 5, 6, 7]).reduceRight(function(previous, current) {
previous.push(current);
return previous;
}, []);
console.log(arr);
In ES6 this could be written as
reverse = (array) => array.map(array.pop, [... array]);
No need to pop anything... Just iterate through the existing array in reverse order to make your new one.
function reverse(array){
var output = [];
for (var i = array.length - 1; i> -1; i--){
output.push(array[i]);
}
return output;
}
console.log(reverse([1,2,3,4,5,6,7]));
Edit after answer got accepted.
A link in a comment on your opening post made me test my way VS the accepted answer's way. I was pleased to see that my way, at least in my case, turned out to be faster every single time. By a small margin but, faster non the less.
Here's the copy/paste of what I used to test it (tested from Firefox developer scratch pad):
function reverseMyWay(array){
var output = [];
for (var i = array.length - 1; i> -1; i--){
output.push(array[i]);
}
return output;
}
function reverseTheirWay(array) {
var output = [];
while (array.length) {
output.push(array.pop());
}
return output;
}
function JustDoIt(){
console.log("their way starts")
var startOf = new Date().getTime();
for(var p = 0; p < 10000; p++)
{
console.log(reverseTheirWay([7,6,5,4,3,2,1]))
}
var endOf = new Date().getTime();
console.log("ran for " + (endOf - startOf) + " ms");
console.log("their way ends")
}
function JustDoIMyWay(){
console.log("my way starts")
var startOf = new Date().getTime();
for(var p = 0; p < 10000; p++)
{
console.log(reverseMyWay([7,6,5,4,3,2,1]))
}
var endOf = new Date().getTime();
console.log("ran for " + (endOf - startOf) + " ms");
console.log("my way ends")
}
JustDoIt();
JustDoIMyWay();
Solution to reverse an array without using built-in function and extra space.
let arr = [1, 2, 3, 4, 5, 6, 7];
let n = arr.length-1;
for(let i=0; i<=n/2; i++) {
let temp = arr[i];
arr[i] = arr[n-i];
arr[n-i] = temp;
}
console.log(arr);
Do it in a reverse way, Because when you do .pop() every time the array's length got affected.
function reverse(array){
var output = [];
for (var i = array.length; i > 0; i--){
output.push(array.pop());
}
return output;
}
console.log(reverse([1,2,3,4,5,6,7]));
Or you could cache the length of the array in a variable before popping out from the array,
function reverse(array){
var output = [];
for (var i = 0, len= array.length; i< len; i++){
output.push(array.pop());
}
return output;
}
console.log(reverse([1,2,3,4,5,6,7]));
You are modifying the existing array with your reverse function, which is affecting array.length.
Don't pop off the array, just access the item in the array and unshift the item on the new array so that the first element of the existing array becomes the last element of the new array:
function reverse(array){
var output = [],
i;
for (i = 0; i < array.length; i++){
output.unshift(array[i]);
}
return output;
}
console.log(reverse([1,2,3,4,5,6,7]));
If you'd like to modify the array in-place similar to how Array.prototype.reverse does (it's generally inadvisable to cause side-effects), you can splice the array, and unshift the item back on at the beginning:
function reverse(array) {
var i,
tmp;
for (i = 1; i < array.length; i++) {
tmp = array.splice(i, 1)[0];
array.unshift(tmp);
}
return array;
}
var a = [1, 2, 3, 4, 5];
console.log('reverse result', reverse(a));
console.log('a', a);
This piece allows to reverse the array in place, without pop, splice, or push.
var arr = [1, 2, 3, 4, 5];
function reverseArrayInPlace(arr2) {
var half = Math.floor(arr2.length / 2);
for (var i = 0; i < half; i++) {
var temp = arr2[arr2.length - 1 - i];
arr2[arr2.length - 1 - i] = arr2[i];
arr2[i] = temp;
}
return arr2;
}
As you pop items off the first array, it's length changes and your loop count is shortened. You need to cache the original length of the original array so that the loop will run the correct amount of times.
function reverse(array){
var output = [];
var len = array.length;
for (var i = 0; i< len; i++){
output.push(array.pop());
}
return output;
}
console.log(reverse([1,2,3,4,5,6,7]));
You're modifying the original array and changing it's size. instead of a for loop you could use a while
function reverse(array){
var output = [];
while(array.length){
//this removes the last element making the length smaller
output.push(array.pop());
}
return output;
}
console.log(reverse([1,2,3,4,5,6,7]));
function rvrc(arr) {
for (let i = 0; i < arr.length / 2; i++) {
const buffer = arr[i];
arr[i] = arr[arr.length - 1 - i];
arr[arr.length - 1 - i] = buffer;
}
};
const reverse = (array)=>{
var output = [];
for(let i=array.length; i>0; i--){
output.push(array.pop());
}
console.log(output);
}
reverse([1, 2, 3, 4, 5, 6, 7, 8]);
This happens because every time you do array.pop(), whilst it does return the last index in the array, it also removes it from the array. The loop recalculates the length of the array at each iteration. Because the array gets 1 index shorter at each iteration, you get a much shorter array returned from the function.
This piece of code will work without using a second array. It is using the built in method splice.
function reverse(array){
for (let i = 0; i < array.length; i++) {
array.splice(i, 0, array.splice(array.length - 1)[0]);
}
return array;
}
Here, let's define the function
function rev(arr) {
const na = [];
for (let i=0; i<arr.length; i++) {
na.push(arr[arr.length-i])
}
return na;
}
Let's say your array is defined as 'abca' and contains ['a','b','c','d','e','foo','bar']
We would do:
var reva = rev(abca)
This would make 'reva' return ['bar','foo','e','d','c','b','a'].
I hope I helped!
You can use .map as it is perfect for this situation and is only 1 line:
const reverse = a =>{ i=a.length; return a.map(_=>a[i-=1]) }
This will take the array, and for each index, change it to the length of the array - index, or the opposite side of the array.
with reverse for loop
let array = ["ahmet", "mehmet", "aslı"]
length = array.length
newArray = [];
for (let i = length-1; i >-1; i--) {
newArray.push(array[i])
}
console.log(newArray)
And this one:
function reverseArray(arr) {
let top = arr.length - 1;
let bottom = 0;
let swap = 0;
while (top - bottom >= 1) {
swap = arr[bottom];
arr[bottom] = arr[top];
arr[top] = swap;
bottom++;
top--;
}
}
function reverse(arr) {
for (let i = 0; i < arr.length - 1; i++) {
arr.splice(i, 0, arr.pop())
}
return arr;
}
console.log(reverse([1, 2, 3, 4, 5]))
//without another array
reverse=a=>a.map((x,y)=>a[a.length-1-y])
reverse=a=>a.map((x,y)=>a[a.length-1-y])
console.log(reverse(["Works","It","One","Line"]))
One of shortest:
let reverse = arr = arr.map(arr.pop, [...arr])
This is an old question, but someone may find this helpful.
There are two main ways to do it:
First, out of place, you basically push the last element to a new array, and use the new array:
function arrReverse(arr) {
let newArr = [];
for(let i = 0; i<arr.length; i++){
newArr.push(arr.length -1 -i);
}
return newArr;
}
arrReverse([0,1,2,3,4,5,6,7,8,9]);
Then there's in place. This is a bit tricky, but the way I think of it is like having four objects in front of you. You need to hold the first in your hand, then move the last item to the first place, and then place the item in your hand in the last place.
Afterwards, you increase the leftmost side by one and decrease the rightmost side by one:
function reverseArr(arr) {
let lh;
for(let i = 0; i<arr.length/2; i++){
lh = arr[i];
arr[i] = arr[arr.length -i -1];
arr[arr.length -i -1] = lh;
}
return arr;
}
reverseArr([0,1,2,3,4,5,6,7,8,9]);
Like so. I even named my variable lh for "left hand" to help the idea along.
Understanding arrays is massively important, and figuring out how they work will not only save you from unnecessarily long and tedious ways of solving this, but will also help you grasp certain data concepts way better!
I found a way of reversing the array this way:
function reverse(arr){
for (let i = arr.length-1; i >= 0; i--){
arr.splice(i, 0, arr.shift());
}
return arr;
}
Without Using any Pre-define function
const reverseArray = (array) => {
for (let i = 0; i < Math.floor(array.length / 2); i++) {
[array[i], array[array.length - i - 1]] = [
array[array.length - i - 1],
array[i]
];
}
return array;
};
let array = [1,2,3,4,5,6];
const reverse = (array) => {
let reversed = [];
for(let i = array.length - 1; i >= 0; i--){
reversed[array.length - i] = array[i];
}
return reversed;
}
console.log(reverse(array))
you can use the two pointers approach
example
function reverseArrayTwoPointers(arr = [1, 2, 3, 4, 5]) {
let p1 = 0;
let p2 = arr.length - 1;
while (p2 > p1) {
const temp = arr[p1];
arr[p1] = arr[p2];
arr[p2] = temp;
p1++;
p2--;
}
return arr;
}
to return [5,4,3,2,1]
example on vscode
let checkValue = ["h","a","p","p","y"]
let reverseValue = [];
checkValue.map((data, i) => {
x = checkValue.length - (i + 1);
reverseValue[x] = data;
})
function reverse(str1) {
let newstr = [];
let count = 0;
for (let i = str1.length - 1; i >= 0; i--) {
newstr[count] = str1[i];
count++;
}
return newstr;
}
reverse(['x','y','z']);
Array=[2,3,4,5]
for(var i=0;i<Array.length/2;i++){
var temp =Array[i];
Array[i]=Array[Array.length-i-1]
Array[Array.length-i-1]=temp
}
console.log(Array) //[5,4,3,2]

Javascript - Access elements of array using an array of indices

Is there a shortcut to accessing elements of an array using an array of indices rather than going one index at a time?
Example (this doesn't work):
var array = ["One", "Two", "Three", "Four"];
var indices = [1, 3];
var result = array[indices];
where result would be ["Two", "Four"].
You can make one and have it available to all Arrays if you've no qualms about extending native prototypes in your environment.
Array.prototype.atIndices = function(ind) {
var result = [];
for (var i = 0; i < arguments.length; i++) {
if (arguments[i] in this)
result.push(this[arguments[i]])
}
return result;
}
var result = array.atIndices(1,3);
You could also have it check to see if an Array was passed, or a mix of indices and Arrays.
Array.prototype.atIndices = function(ind) {
var result = [];
for (var i = 0; i < arguments.length; i++) {
if (Array.isArray(arguments[i]))
result.push.apply(result, this.atIndices.apply(this, arguments[i]))
else if (arguments[i] in this)
result.push(this[arguments[i]])
}
return result;
}
This will actually flatten out all Arrays, so they could be as deeply nested as you want.
var result = array.atIndices(1, [3, [5]]);
Now there is:
function pluck(arr, indices) {
var result = [],
i = 0,
len = indices.length;
for (; i < len; i++) {
result.push(arr[indices[i]]);
}
return result;
}
As an alternative to rolling your own, if you have access to Lo-Dash (which you should totally use because it is awesome) its at function does exactly what you want.
Your usage would be:
var result = _.at(array, indices);
See: http://lodash.com/docs#at

Finding missing array in array of arrays

I need to find a missing array in an "array of arrays". I started by finding this function below (on StackOverflow):
function findDeselectedItem(CurrentArray, PreviousArray) {
var CurrentArrSize = CurrentArray.length;
var PreviousArrSize = PreviousArray.length;
var deselectedItem = [];
// loop through previous array
for(var j = 0; j < PreviousArrSize; j++) {
// look for same thing in new array
if (CurrentArray.indexOf(PreviousArray[j]) == -1)
deselectedItem.push(PreviousArray[j]);
}
return deselectedItem;
}
This works just fine if you did something like this:
oldarray = ["hi", "ho", "hey"];
newarray = ["hi", "hey"];
Using findDeselectedItem(newarray, oldarray) would return ["ho"].
However, my content looks like this:
oldarray = [["James", 17, 1], ["Olivia", 16, 0], ["Liam", 18, 1]];
newarray = [["Olivia", 16, 0], ["James", 17, 1]];
How can I adapt the function above so that it returns the missing array containing 'Liam'.
Thanks
I would make a hash with the name as a key. That would make finding missing content trivial and very fast. You can then optimize the method by not rebuilding the hash every time, but only when it's really necessary.
var oldArray = [["James", 17, 1], ["Olivia", 16, 0], ["Liam", 18, 1]];
var newArray = [["Olivia", 16, 0], ["James", 17, 1]];
function findDeselectedItems(oldArray, newArray)
{
var results = [];
var hash = {};
for (var i=0; i<newArray.length; i++) {
hash[newArray[i].join(',')] = true;
}
for (var i=0; i<oldArray.length; i++) {
if (!hash[oldArray[i].join(',')]) {
results.push(oldArray[i]);
}
}
return results;
}
The problem may be that indexOf uses strict equality. I.e. if an item in the 'previous' array isn't literally also in the 'current' array, it will report it to not be in there.
You will have to iterate over the values yourself (instead of using indexOf) and check if the array contains something that is 'the same as' (but not literally the same) the array.
I.e. if I didn't explain myself well enough take a look at this;
['bob'] == ['bob']; //false
//therefore
[['bob']].indexOf(['bob']); //-1
I hope that this helps you,
function findDeselectedItem(CurrentArray, PreviousArray) {
var CurrentArrSize = CurrentArray.length;
var PreviousArrSize = PreviousArray.length;
var deselectedItem = [];
// loop through previous array
for(var j = 0; j < PreviousArrSize; j++) {
var checkArray = PreviousArrSize[j];
// loop through 2nd array to match both array
for(var i = 0; i < CurrentArrSize; i++) {
// look for same thing in new array
if (CurrentArray[i].indexOf(checkArray) == -1)
deselectedItem.push(CurrentArray[i]);
}
}
return deselectedItem;
}
#KarelG: nice and quick solution but should it not be var checkArray = PreviousArr[j]; instead of var checkArray = PreviousArrSize[j]; ?
function findDeselectedItem(CurrentArray, PreviousArray) {
var CurrentArrSize = CurrentArray.length;
var PreviousArrSize = PreviousArray.length;
var deselectedItem = [];
var selectedIndices = [];
// loop through previous array
for(var j = 0; j < PreviousArrSize; j++) {
for(k=0; k < CurrentArrSize ; k++){
if (CurrentArray[k].toString() === PreviousArray[j].toString()){
selectedIndices.push(j);
break;
}
}
}
for(var l = 0; l < PreviousArrSize; l++){
if(selectedIndices.indexOf(l) === -1){
deselectedItem.push(PreviousArray[l]);
}
}
return deselectedItem;
}
I don't think you can use indexOf to compare two arrays. You need a deeper comparison. Although this code could be written another way, you could do this with an array comparison function and using Array.some() to filter through your elements. Here's an example and a fiddle;
// Credit http://stackoverflow.com/questions/7837456/comparing-two-arrays-in-javascript
// attach the .compare method to Array's prototype to call it on any array
Array.prototype.compare = function (array) {
// if the other array is a falsy value, return
if (!array)
return false;
// compare lengths - can save a lot of time
if (this.length != array.length)
return false;
for (var i = 0; i < this.length; i++) {
// Check if we have nested arrays
if (this[i] instanceof Array && array[i] instanceof Array) {
// recurse into the nested arrays
if (!this[i].compare(array[i]))
return false;
}
else if (this[i] != array[i]) {
// Warning - two different object instances will never be equal: {x:20} != {x:20}
return false;
}
}
return true;
}
function findDeselectedItem(CurrentArray, PreviousArray) {
var CurrentArrSize = CurrentArray.length;
var PreviousArrSize = PreviousArray.length;
var deselectedItem = [];
// loop through previous array
for (var j = 0; j < PreviousArrSize; j++) {
// look for same thing in new array
CurrentArray.some(function (a, idx) {
if(PreviousArray[j].compare(a) == false) {
deselectedItem.push(PreviousArray[j]);
return true;
}
});
}
return deselectedItem;
}
var oldarray =[["James", 17, 1], ["Olivia", 16, 0], ["Liam", 18, 1]];
var newarray =[["Olivia", 16, 0], ["James", 17, 1]];
console.log(findDeselectedItem(newarray, oldarray));

Javascript - sort without sort

Problem in Javascript
I previously asked this question Javascript 2D array sorting - by numerical value with a solution provided using the sort function, which I have tried to use without sucsess. Turns out the sort function isn't correctly within the tool I am using, it sorts 5 values and then stops working - and is not working using negative values etc. Spoken to their development team and been told to upgrade - not an option.
Tl:dr - I need to sort with out using the inbuilt sort function.
I have two arrays
values = [1000, 2356, 3456778, 7645748, -2324, 348845.45, -2345666]
labels = ["ValA", "ValB", "ValC", "ValD", "ValE", "ValF", "ValG", "ValH"]
These need to be combined to show [1000,ValA, etc] with the largest value appearing first.
Without the inbuilt sort functionality, I am at a loss on how to proceed. I tried using the Math.Max to cycle through the array, but when I'd combined these two arrays the function stopped working.
I am not sure whether to combine these two individual arrays, or to keep them separate so that the sorting is simpler, remembering the original index and links to the label.
Any thoughts or questions welcome, I am truly stumped and not a developer by trade so sure there is some kind soul out there who maybe able to support me.
Thanks
Expected output
[7645748, ValD]
[3456778, ValC]
[348845.45, ValF]
[2356, ValB]
[2324, ValE]
[1000, ValA]
[-2345666, ValG]
Create an array of customr objects and pupoluate with the data
for (var i = 0; i < values.length; i++) {
myArray[i].value = values[i];
myArray[i].label = labels[i];
}
Then implement your own bubblesort algorithm :
for (var j = 0; j < myArray.length - 1; j++) {
for (var i = 0, swapping; i < myArray.length - 1; i++) {
if (myArray[i].value > myArray[i + 1].value) {
swapping = myArray[i + 1];
myArray[i + 1] = myArray[i];
myArray[i] = swapping;
};
};
};
var list = ['z','b', 'a', 'y'];
for (var j = 0; j < list.length - 1; j++) {
for (var i = 0, swapping; i < list.length - 1; i++) {
if (list[i]> list[i + 1]) {
swapping = list[i + 1];
list[i + 1] = list[i];
list[i] = swapping;
};
};
};
output will be = ["a", "b", "y", "z"]
This method is a very simple and easy way to solve a sort problem in an array without a sort() method.
function sortArray(arr) {
var temp = [];
if (Array.isArray(arr)) {
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length; j++) {
if (arr[i] < arr[j]) {
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
}
return arr;
}
}
console.log(sortArray([2, 6, 0, 4, 3, 4, 3, 5, 9, 6, 12, 43, 6]));
// It will work for both Python or JS code
let b = ["ValA", "ValB", "ValC", "ValD", "ValE", "ValF", "ValG", "ValH"]
for(let i=0;i<b.length-1;i++){
for(let j=i+1;j<b.length;j++)
{
if(b[j]<b[i])
{
temp = b[j]
b[j]=b[i]
b[i] = temp
}
}
}
console.log(b)

how to compare two arrays of different length if you dont know the length of each one in javascript?

I am stuck in this. I got 2 arrays, I don't know the length of each one, they can be the same length or no, I don't know, but I need to create a new array with the numbers no common in just a (2, 10).
For this case:
var a = [2,4,10];
var b = [1,4];
var newArray = [];
if(a.length >= b.length ){
for(var i =0; i < a.length; i++){
for(var j =0; j < b.length; j++){
if(a[i] !=b [j]){
newArray.push(b);
}
}
}
}else{}
I don't know why my code never reach the first condition and I don't know what to do when b has more length than a.
It seems that you have a logic error in your code, if I am understanding your requirements correctly.
This code will put all elements that are in a that are not in b, into newArray.
var a = [2, 4, 10];
var b = [1, 4];
var newArray = [];
for (var i = 0; i < a.length; i++) {
// we want to know if a[i] is found in b
var match = false; // we haven't found it yet
for (var j = 0; j < b.length; j++) {
if (a[i] == b[j]) {
// we have found a[i] in b, so we can stop searching
match = true;
break;
}
// if we never find a[i] in b, the for loop will simply end,
// and match will remain false
}
// add a[i] to newArray only if we didn't find a match.
if (!match) {
newArray.push(a[i]);
}
}
To clarify, if
a = [2, 4, 10];
b = [4, 3, 11, 12];
then newArray will be [2,10]
Try this
var a = [2,4,10];
var b = [1,4];
var nonCommonArray = [];
for(var i=0;i<a.length;i++){
if(!eleContainsInArray(b,a[i])){
nonCommonArray.push(a[i]);
}
}
function eleContainsInArray(arr,element){
if(arr != null && arr.length >0){
for(var i=0;i<arr.length;i++){
if(arr[i] == element)
return true;
}
}
return false;
}
I found this solution just using the filter() and include() methods, a very and short easy one.
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
The includes() method determines whether an array includes a certain value among its entries, returning true or false as appropriate.
function compareArrays(a, b) {
return a.filter(e => b.includes(e));
}

Categories

Resources