Javascript array is syncing with another assigned array - javascript

I've been racking my brain trying to figure out why these arrays are syncing after I assign one to the other. The output should be "1, 2, 3, 4" but instead it's "5, 6, 7, 8". Do I need to copy the arrays differently?
var firstArray = [1, 2, 3, 4];
var secondArray = [5, 6, 7, 8];
for (i = 0; i < firstArray.length; i++) {
var myTempArray = firstArray;
myTempArray[i] = secondArray[i];
}
console.log("Result: " + firstArray);
Expected output:
Result: 1,2,3,4
Actual output:
Result: 5,6,7,8
How do I alter the second array without changing the first array?

Arrays are mutable objects. So they just contain references. You need to "copy" an array in order to make a copy, not just assign like primitive objects. To copy an array, there are various methods. One best method is:
myTempArray = firstArray.slice();
What you are doing is a shallow copy:
Also, another big issue is that, you have the array assignment inside the loop, which keeps the myTempArray changing. You need to take it out of the loop. Your final code should look like:
var firstArray = [1, 2, 3, 4];
var secondArray = [5, 6, 7, 8];
var myTempArray = firstArray.slice();
for (i = 0; i < firstArray.length; i++) {
myTempArray[i] = secondArray[i];
}
console.log("Result: " + firstArray);

Related

Is this considered a selection sort?

I was practicing a while ago and came across selection sort. After some research across difference sources, there are some that declare an array then delete the current min location while others swap within the array
I tried to use ES6 for some trivial functions, did not use map since I wanted to understand the loop on a whiteboard.
Is this considered a selection sort?
selectionSortNoSwap = list)= => {
const result = [];
for (let i = 0; i < list; i++) {
const min = Math.min(...list);
const minIndex = list.indexOf(min);
result.push(min);
list.splice(minIndex, 1);
}
return result;
};
selectionSortNoSwap([3, 5, 2, 1, 4]);
Thank you
No. True selection sort sorts in-place, rather than creating another array. That is, given:
[3, 5, 2, 1, 4]
after the first iteration, a selection sort should produce the following data structure in memory:
[1, 5, 2, 3, 4]
where the 1 and 3 have been exchanged - and not
[3, 5, 2, 4]
[1]
If elements are not swapped with each other, it's not selection sort.
To sort in-place, you'd need something like
const selectionSort = (list) => {
for (let i = 0; i < list.length; i++) {
// for convenience - or use a for loop
const min = Math.min(...list.slice(i));
const minIndex = list.indexOf(min, i);
[list[i], list[minIndex]] = [list[minIndex], list[i]];
}
return list;
};
console.log(selectionSort([3, 5, 2, 1, 4]));

What is another way to reverse an array without modifying the original and using .reverse()? [duplicate]

This question already has answers here:
Reverse array in Javascript without mutating original array
(15 answers)
Closed 2 years ago.
I have been participating in some javaScript challenges and solved the reverse array challenge without modifying the original using the spread operator. I enjoy solving problems in different ways so i'm curious to find out from you. In what other way would you have solved it or would you solve it (excluding high order functions like map etc) ?
var newArray = [1,2,3,4,5,6];
const reverseArray = () => {
let arr = [...newArray];
for(let i = 0; i <= arr.length; i++){
arr.pop(i)
arr.unshift(i);
}
return arr
}
console.log(reverseArray())
You can use reverse();
var newArray = [1, 2, 3, 4, 5, 6];
var reverse = newArray.reverse();
console.log(reverse)
Use a for loop with increment to set index and then decrement value and push into array
var myArray = [1, 2, 3, 4, 5, 6, 7, 8];
function reverseArray(myArray) { // create a function and pass our array into it
var newArray = []; // define an empty array
for (var i = myArray.length - 1; i >= 0; i--) { // set for loop, declare a decrement for index as i - 1 to adjust for index, if greater than or equal to 0, decrement i
newArray.push(myArray[i]); // push the value into newArray
}
return newArray; // return newArray
}
console.log(reverseArray(myArray));
Use slice() reverse() and map() together index and value through function.
var myArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var div = document.getElementById('div')
function sliceMap() {
reverseArray = myArray.slice(0).reverse().map(
function(value) {
return value;
}
);
div.innerHTML = reverseArray;
}
console.log(sliceMap())
<div id="div"></div>
Mapping values and then using unshift to reverse them.
var myArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var reverseArray = [];
myArray.map((value) => {
reverseArray.unshift(value);
});
console.log(reverseArray)

JavaScript forEach loop separating an array into other arrays using .push()

New here and been trying to figure this out for a bit now. Can't seem to find the answer.
Problem: trying to separate all numbers from 5 upwards into a separate array "bigNumbers". All other numbers to "smallNumbers"
Here's what I have so far:
let allNumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let bigNumbers = [];
let smallNumbers = [];
allNumbers.forEach(function (a) {
if(allNumbers >= 5) {
return allNumbers.push(bigNumbers);
} else {
return allNumbers.push(smallNumbers);
}
});
Might be taking the wrong approach entirely here using the .push() method. Any feedback is appreciated.
You're testing the wrong variable, it should be a, not allNumbers. And the argument to .push() is the value you want to push onto the array, not the array to push onto. There's also no need to use return, since forEach doesn't use the return values.
let allNumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let bigNumbers = [];
let smallNumbers = [];
allNumbers.forEach(function (a) {
if(a >= 5) {
bigNumbers.push(a);
} else {
smallNumbers.push(a);
}
});
console.log("Big: " + JSON.stringify(bigNumbers));
console.log("Small: " + JSON.stringify(smallNumbers));
Trouble is in your if (allNumbers >= 5)
What you want is to know if the current number being iterated is greater than 5:
if (a >= 5)...

How to find common elements only between 2 arrays in jquery [duplicate]

This question already has answers here:
Simplest code for array intersection in javascript
(40 answers)
Closed 8 years ago.
var array1 = [1, 2, 3, 4, 5, 6];
var array2 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
I have two arrays like above. Now I want to do the following in MVC 4 with jQuery.
If every elements of both arrays are equal then show a message/alert. e.g. "All records already existing."
If every elements of both the arrays are different then just add them all in a "VAR", e.g. var resultset = .... (where 7,8,9 will stored)
If few elements common between two arrays then for the common elements show a message with element, e.g. "Record 1,2,3,4,5,6 are already exists" and add the different elements in "VAR", e.g. var resultset = .... (where 7,8,9 will stored). Both the message and difference elements collection will perform at the same time.
Try this:
var array1 = [1, 2, 3, 4, 5, 6],
array2 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var common = $.grep(array1, function(element) {
return $.inArray(element, array2 ) !== -1;
});
console.log(common); // returns [1, 2, 3, 4, 5, 6];
var array3 = array2.filter(function(obj) { return array1.indexOf(obj) == -1; });
// returns [7,8,9];
Here is my version
function diff(arr1, arr2) {
var obj = {}, matched = [],
unmatched = [];
for (var i = 0, l = arr1.length; i < l; i++) {
obj[arr1[i]] = (obj[arr1[i]] || 0) + 1;
}
for (i = 0; i < arr2.length; i++) {
var val = arr2[i];
if (val in obj) {
matched.push(val);
} else {
unmatched.push(val);
}
}
// Here you can find how many times an element is repeating.
console.log(obj);
// Here you can find what are matching.
console.log(matched);
// Here you can check whether they are equal or not.
console.log('Both are equal ? :' +
matched.length === a.length);
// Here you can find what are different
console.log(unmatched);
}
If you do this kind of thing regularly, you may be interested in a Set object that makes this kind of stuff pretty easy:
var array1 = [1, 2, 3, 4, 5, 6];
var array2 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var common = new Set(array1).intersection(array2).keys();
The open source Set object (one simple source file) is here: https://github.com/jfriend00/Javascript-Set/blob/master/set.js
Along with the intersection() method used here, it has all sorts of other set operations (union, difference, subset, superset, add, remove ...).
Working demo: http://jsfiddle.net/jfriend00/5SCdD/

Best way to return duplicate elements in an Array

Here is the way I am using to return duplicate elements.. But I am facing most dangerous performance issues like browser close etc when my array have large number of items with long texts..
var arr = [9, 9, 111, 2, 3, 4, 4, 5, 7];
var sorted_arr = arr.sort();
var results = [];
for (var i = 0; i < arr.length - 1; i++) {
if (sorted_arr[i + 1] == sorted_arr[i]) {
results.push(sorted_arr[i]);
}
}
alert(results);
Please suggest me a best way of doing this
i don't get exactly what you want, but if you need to return duplicates you could use a cache object. this works with number or string or whatever.
var arr = [9, 9, 111, 2, 3, 4, 4, 5, 7];
var cache = {};
var results = [];
for (var i = 0, len = arr.length; i < len; i++) {
if(cache[arr[i]] === true){
results.push(arr[i]);
}else{
cache[arr[i]] = true;
}
}
console.log(results);//returns an array with 9 and 4
Of course you can do other things like deleting multiple items etc. etc.
EDIT - i've written a blog entry on how to remove duplicates from an array
If you have array filter, you also have indexOf and lastIndexOf,
and you can return the duplicates without doing the sort.
var results, arr= [9, 9, 111, 2, 3, 4, 4, 5, 4, 7];
if(arr.filter){
results= arr.filter(function(itm, i){
return arr.lastIndexOf(itm)== i && arr.indexOf(itm)!= i;
});
}
else// use your loop method
alert(results)
/* returned value: (Array)
9,4
*/
Assuming Nicola's solution doesn't work for you (since it uses about as much memory as the original solution: two elements stored per element in the input, worst-case), you can use the slower process of repeatedly searching your input.
This requires the Array.indexOf method from ECMAScript 5. A lot of browsers have it. For alternatives, see How do I check if an array includes an object in JavaScript?.
var arr = [9, 9, 111, 2, 3, 4, 4, 5, 7];
var results = [];
for (var i = 0, len = arr.length - 1; i < len; i++) {
if((results.indexOf(arr[i]) == -1) && (arr.indexOf(arr[i], i + 1) != -1)) {
results.push(arr[i]);
}
}
console.log(results);
This uses no more memory than the input arr plus the output results, but it's an O(N^2) algorithm and doesn't have to modify arr.
Your method relies on a sort, which may or may not be one reason you run out of space/time.
The canonical way to remove duplicates is to keep a hash map of the keys (an object in JS). The object keys you get back won't necessarily be in the order you want; you don't specify if you want the results ordered as well, but they are now.
You could null out the original array, since you no longer require it; when it gets collected is up to the JS engine though.
You could remove duplicates "in place" by keeping a "current index" into the sorted array, and increment it only when you move a non-duplicated element "down" from the counter index, then truncate the array that you return.
Combining the last two techniques should mean that in general you'll only have a single array with a valid reference.
Edit Example. Setting length explicitly, as .slice() creates a new array.
var have = {};
var arr = [9, 9, 111, 2, 3, 4, 4, 5, 7];
arr = arr.sort();
for (var rIdx = 0, i = 0; i < arr.length; i++) {
if (have[arr[i]]) {
arr[rIdx++] = arr[i];
} else {
have[arr[i]] = true;
}
}
arr.length = rIdx;
console.log(arr);

Categories