Remove an item from a copy of an array without removing it from the original array - javascript

How can I remove an object from a copy of an array without removing it from the original?
I have a global variable :
var userTrickList = [];
And inside a function, I make a copy of that global array :
var tempUserTrickList = userTrickList;
Then I use the removeItem function that I created to remove a certain object.
removeItem(considerTrick.IDName, tempUserTrickList);
function removeItem(item, list) {
//takes a string as 'item', finds in the array as 'list',
//then removes it from the list.
for(var i = 0; i < list.length; i++)
{
if(item === list[i])
{
list.splice(i,1);
}
}
}
My problem is, this function removes it from the userTrickList too.
Any ideas? It's definitely a problem in "removeItem(considerTrick.IDName, tempUserTrickList);", but I can't think of a solution.

Use .slice(0) to clone an array.
var tempUserTrickList = userTrickList.slice(0);
Credits:
http://davidwalsh.name/javascript-clone-array

use this function for your requirement
function removeElementFromArray(data,target) {
var temp=new Array();
for ( var i = 0; i < data.length; i++) {
if(data[i]!=target){
temp.push(data[i]);
}
}
return temp; }
here data is original array and target is the element you want to remove from array
this function will return array without containing the removed item.

Try, It copy the original array
var tempUserTrickList = JSON.parse(JSON.stringify(userTrickList));
Demo CopyArray

for (i = 0, l = arr.length; i < l; i++) {
if (arr[i] === item) {
arr.splice(i, 1);
i -= 1;
l -= 1;
}
}

Daniel's method of cloning an array is absolutely correct, but since I don't see an ES6-oriented answer, I'll offer up an alternative solution:
We can just as easily use the spread operator to clone an array, so we don't have to use the slice call.
const arr = [1, 2, 3];
const copy = [...arr];
copy.pop();
console.log(arr); // returns [1, 2, 3]
console.log(copy); // returns [1, 2]

Related

Array not reassigning after change

I have an array that contains elements my goal is to slice some of the elements inside the array, then later I want to reassign the original array with a new array which is a sublist of the original array but it seems like I can't make that happen please help.
let arr = [1,2,3,4,5]
function subList(arr){
for(let i = 0; i < arr.length; i++){
let res = arr.slice(0,i)
if(i === 3){
arr = res;
}
}
}
subList(arr)
console.log(arr)
// expected output [1,2,3]
There are a lot of ways to do it.
Why it isn't working for you:
You are passing the arr into the variable and since it is an object ideally any change you make to it should be reflected outside. But you aren't actually mutating/changing anything in your passed argument, you are reassigning it (with arr=res). So that will not make any change to the arr outside.
If you do something like .push(),.pop(), which are operations on the array without reassigning it, that should actually change it.
Example modifying your code with operations that actually modify the array instead of replacing it splice() , push:
let arr = [1,2,3,4,5]
function subList(arr){
for(let i = 0; i < arr.length; i++){
let res = arr.slice(0,i)
if(i === 3){
arr.splice(0,arr.length);
arr.push(...res);
break;
}
}
}
subList(arr)
console.log(arr)
Pass in an index to the function and just return arr.slice(0, i);.
let arr = [1, 2, 3, 4, 5]
function subList(arr, i) {
return arr.slice(0, i);
}
console.log(subList(arr, 3));
let list = [1,2,3,4,5]
function subList(arr,n){
for(let i = 0; i < arr.length; i++){
if(i === 3){
let res = arr.slice(0,i)
list = res;
}
}
}
subList(list,0)
console.log(list)

Getting wrong result with Number.isInteger() method, javascript

I've been trying the Number.isInteger() method on chrome console.
and after doing a for loop and checking the result with the console.log(arr); I'm getting an array with only one value of 1. like this [1];
var arr = [1,2,3,'some','string'];
for (var i = 0; i < arr.length; i++) {
if (Number.isInteger(arr[i])) {
arr.splice(arr.indexOf(arr[i], 1));
}
}
Any one have an idea, if I'm doing it wrong or something. thanks for help.
You have a major problem, you are continually removing items from the array while looping through it. You have to go back one step (i--) every time an item is removed.
var arr = [1,2,3,'some','string'];
for (var i = 0; i < arr.length; i++) {
if (!isNaN(arr[i])) { // isNaN return true if it's not a valid number, so we have to inverse the test
arr.splice(i, 1); // if it's a valid number remove the element at the index i (no need to search for the index using indexOf, we already have it its i)
i--; // if we remove an element, we have to go back one step (or we will leave one item behind every time we remove another)
}
}
console.log(arr);
You could use typeof instead:
var arr = [1,2,3,'some','string'];
for (var i = 0; i < arr.length; i++) {
if (typeof arr[i] == 'number') {
arr.splice(arr.indexOf(arr[i], 1));
}
}
The `.splice()' method makes changes to the array itself.
So for each iteration of the array, you are changing it fundamentally.
If you want the array to include only integers:
var arr = [1,2,3,'some','string'];
var newArray = [];
arr.forEach(function(element) {
if (Number.isInteger(element)){
newArray.push(element);
}
});
console.log(newArray);

push to object if not exists from params

I've been trying and searching how to loop through the params to check if those already exist in an array, i haven't got it fully working but when there is a duplicate value it dose not return at all.
The idear is pass multiple values is param then loop through those vals and only push if it dose not exist in the array.
var arr = [7,3,1];
function pushNew(obj) {
var prams = obj;
for(var k = 0; k < obj.length; k++){
for (var i = 0; i < arr.length; i++) {
if (arr[i] == prams[k]) {
return;
}
}
array.push(prams[k]);
}
// console.info(arr);
}
pushNew([2,7,4]);
A short and more modern way to just get all the unique values is to use Array.from with Set. A Set is an array-like structure that will only hold unique values. Array.from converts an array-like structure into a real array.
In your case, you can just concat both arrays, pass them to Set to remove the duplicates, and use Array.from to convert it back to a regular array.
var arr1 = [1, 2, 3, 4, 5];
var arr2 = [3, 4, 5, 6, 7];
var result = Array.from(new Set(arr1.concat(arr2)));
document.write(JSON.stringify(result));
Actually, your existing code nearly works.
You can set a flag if you find a match in the inner loop and instead of return you should use break to escape the loop. Then use push after the inner loop if a match wasn't found. Also, there is no need for both obj and prams (which I've renamed to params), so:
var arr = [7,3,1];
function pushNew(params) {
var found;
for(var k=0; k<params.length; k++){
// Set found to initial value on each outer loop
found = false;
for (var i=0; i<arr.length; i++) {
// If find match, set flag and break from loop (for efficiency)
if (arr[i] == params[k]) {
found = true;
break;
}
}
// If match not found, push into arr
if (!found) arr.push(params[k]);
}
}
pushNew([7,2])
document.write(arr); // 7,3,1,2
If you want efficient code, consider creating an index and using in:
var arr = [7,3,1];
function addParams(params) {
var index = arr.reduce(function(acc, v) {
acc[v] = true;
return acc;
},{});
params.forEach(function(v) {
if (!(v in index)) arr.push(v);
});
}
addParams([7,3,2]);
document.write(arr);
You can use indexOf to validate if element is present in an array. forEach is another array method which works like loop.
var arr = [7,3,1];
function pushNew(obj) {
//var prams = obj;
obj.forEach(function(item){ // iterate through each element
if(arr.indexOf(item) == -1){ //indexOf return -1 is element is not present in an array
arr.push(item)
}
})
console.log(arr);
}
pushNew([2,7,4]);
Working Jsfiddle
var arr = [7, 3, 1];
function pushNew(obj) {
for (var k = 0; k < obj.length; k++) {
if (arr.indexOf(obj[k]) == -1) {
arr.push(obj[k]);
}
}
}
pushNew([2, 7, 4]);
You can use _.union function of lodash.
_.union([2, 1], [4, 2], [1, 2]);
// → [2, 1, 4]

JavaScript -- search for array values in object

I have an array and an array of objects. I want to search each value in the array in the array of objects and if it doesnt exist, I want to remove the value from the array.
var arr= [1,2,3,4];
var recs = [{id:1},{id:2},{id:3}]; //4 doesnt exist in recs, remove from arr
//arr = [1,2,3];
Heres my attempt. Obviously does not work. I am not sure how I can compare each arr index with all the values in recs before moving on the next arr index:
var arr= [1, 2, 3, 4], index;
var recs = [{a:1},{a:2},{a:3}];
for(var i = 0; i<arr.length; i++){
for(var val in recs[i]){
if(arr[i] != recs[i][val]){
index = arr.indexOf(arr[i]);
arr.splice(index, 1);
}
}
}
thank you!!
If you are okay with leaving your original array instance alone and creating a new one (essentially treating it as immutable)
var newArr = arr.filter(function(num) {
return !recs.every(function(obj) {
return obj.a !== num;
});
});
Detail of the methods used: Array.filter is passed a function, runs that function on each element inside, and then returns a new array with only the elements that returned true in the function.
Array.every works a little similar, but returns a Boolean, true or false. It returns true if all of the elements of the array returned true inside of the function.
var arr= [1, 2, 3, 4];
var recs = [{a:1},{a:2},{a:3}];
// don't use var in for loops.
// Variables declared with var have function scope, so declare them at the top of your function
var i;
var j;
var value;
var found;
// iterate over the array
for (i = 0; i < arr.length; i++)
{
value = arr[i];
found = false;
// iterate over the other array
for (j = 0 ; j < recs.length ; j++)
{
// if we found what we were looking for, make a note and exit loop
if (recs[j].a == value)
{
found = true;
break;
}
}
if (!found)
{
arr.splice(i, 1);
// To compensate the loop's i++, to avoid skipping the next entry
i--;
}
}
alert(arr.join(','));

How to delete multiple items of an array by value?

I am trying to make a removeAll() function, which will remove all elements of an array with that particular value (not index).
The tricky part comes when we make any change to the loop, the indexes tend to move around (making it very hard to make it work like we want) and, restarting the loop every time we make changes is very inefficient on big arrays.
So far, I wrote my own arr.indexOf function (for older IE support), it looks like this:
function arrFind(val, arr) {
for (var i = 0, len = arr.length, rtn = -1; i < len; i++) {
if (arr[i] === val) {
return i;
}
}
return -1;
}
It is easy to remove elements like this:
var myarray = [0, 1, 2, 3, 4];
var tofind = 2;
var stored_index = arrFind(tofind, myarray);
if (stored_index != -1) {
myarray.splice(stored_index, 1);
}
alert(myarray.join(",")); //0,1,3,4
However, as I pointed out earlier, when doing this while looping, we get in trouble.
Any ideas on how to properly remove array items while looping through it?
Loop in reverse order or build a new array with the items that are not to be removed.
Every new browser has an Array filter method:
var myarray=[0,1,2,3,4];
var removal=2;
var newarray=myarray.filter(function(itm){return itm!==removal});
Try this one. You just have to check the indices of the numbers you would like to remove. I have added additional elements in your array.
var myarray = [0, 1, 2, 3, 2, 2, 2, 5, 6];
var indicesToRemove = new Array();
for(i=0;i<myarray.length;i++){
if(myarray[i]===2){ //let's say u wud like to remove all 2
indicesToRemove.push(i); //getting the indices and pushing it in a new array
}
}
for (var j = indicesToRemove.length -1; j >= 0; j--){
myarray.splice(indicesToRemove[j],1);
}
alert(JSON.stringify(myarray)); //myarray will be [0,1,3,5,6]
I wrote this little function where arr is the original array and d1, d2 the values you want removed. I wonder how it could be generalized to an arbitrary number of values to be removed. Well, I'm just a beginner.
function destroyer(arr, d1, d2) {
var lean =[];
for (var i = 0; i<arr.length; i++) {
if (arr[i] != d1 && arr[i] != d2) {
lean.push(arr[i]);
}
}
return lean;

Categories