Remove elements from array except particular one
Asked Answered
K

3

5

I have two arrays. First one is an array of indexes and second one is an array of objects. They look like this:

var nums = [0, 2];
var obj = [Object_1, Object_2, Object_3];

In this particular case I need to remove all "obj" elements except obj[0] and obj[2]. So the result will look like this:

obj = [Object_2]

There are also may be cases when nums = [0, 1, 2] and obj = [Object_1, Object_2, Object_3]; In that case I dont need to remove any elements.

The "obj" length is always greater than "nums" length.

So I started with finding only the elements that I need to save:

nums.forEach(function(key) {
    obj.forEach(function(o, o_key) {
        if (key === o_key) {
            console.log(key, o);
            // deleting remaining elements
        }
    });
});

The question: How can I remove elements that dont meets my condition? I dont need the new array, I want to modify the existing "obj" array. How can I achieve this functionality? Or should I use some another techniques?

Kaon answered 24/5, 2017 at 11:31 Comment(2)
why is in the first case to delete the given indices and in the second case the opposite?Baroda
I agree with @NinaScholz shouldn't the second case be nums = []Yerkovich
B
5

You coudld check if the length of the indices is the same length of the object array and return or delete the objects at the given indices.

It needs a sorted array for indices, because Array#splice changes the length of the array. (With an array with descending sorted indices, you could use Array#forEach instead of Array#reduceRight.)

function mutate(objects, indices) {
    if (objects.length === indices.length) {
        return;
    }
    indices.reduceRight(function (_, i) {
        objects.splice(i, 1);
    }, null);
}

var objects = [{ o: 1 }, { o: 2 }, { o: 3 }];

mutate(objects, [0, 1, 2]);               // keep all items
console.log(objects); 

objects = [{ o: 1 }, { o: 2 }, { o: 3 }]; // delete items at index 0 and 2
mutate(objects, [0, 2]);
console.log(objects);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Baroda answered 24/5, 2017 at 11:43 Comment(2)
What about the opposite? If I want to save items at specified indexes like [0, 2] and delete the element under 1 index? What function instead reduceRight() is better to use? Sorry for disturbing)Kaon
@Luchnik, then i suggest to iterate the objects, get the max value of indices and check the actual index, then splice if necessary.Baroda
S
5

You can do this with a filter, assuming nums is an array on indexes of elements you want to keep.

obj = obj.filter((o, i) => nums.indexOf(i) > -1); 
Swartz answered 24/5, 2017 at 11:36 Comment(5)
OP mentioned not wanting a new arrayLeapt
This doesn't create a new array, it filters the existing oneSwartz
filter returns a new array - see first line in developer.mozilla.org/en/docs/Web/JavaScript/Reference/…Leapt
Yes it does, but I took not wanting a new array in this question to mean that OP didn't want a new variable storing another array. If OP needs the array to be the exact same array then my answer is incorrect. This answer starts with 2 variables holding arrays, and finishes with the same 2 variables holding arrays.Swartz
well too me it seems like the actual array object was important; having the same variable reference pointing to a new object is not really a use case worth considering (what's the point of it?) however maintaining the same object might be important - depending on what the object is used forLeapt
B
5

You coudld check if the length of the indices is the same length of the object array and return or delete the objects at the given indices.

It needs a sorted array for indices, because Array#splice changes the length of the array. (With an array with descending sorted indices, you could use Array#forEach instead of Array#reduceRight.)

function mutate(objects, indices) {
    if (objects.length === indices.length) {
        return;
    }
    indices.reduceRight(function (_, i) {
        objects.splice(i, 1);
    }, null);
}

var objects = [{ o: 1 }, { o: 2 }, { o: 3 }];

mutate(objects, [0, 1, 2]);               // keep all items
console.log(objects); 

objects = [{ o: 1 }, { o: 2 }, { o: 3 }]; // delete items at index 0 and 2
mutate(objects, [0, 2]);
console.log(objects);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Baroda answered 24/5, 2017 at 11:43 Comment(2)
What about the opposite? If I want to save items at specified indexes like [0, 2] and delete the element under 1 index? What function instead reduceRight() is better to use? Sorry for disturbing)Kaon
@Luchnik, then i suggest to iterate the objects, get the max value of indices and check the actual index, then splice if necessary.Baroda
L
1

If you want to keep the same array object, you need to use splice e.g. in a simple reverse for in order to not mess the indices:

for (var i=obj.length-1; i>=0; i--) {
    if (nums.indexOf(i) < 0) {
        obj.splice(i, 1);
    }
}

This is assuming the list of indices (nums) is ordered. If not, we first need to sort it:

var sortedNums = nums.sort(function (a, b) {  return a - b;  });

And then use the sortedNums to check the indexOf

Leapt answered 24/5, 2017 at 11:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.