My data is animalCount: {Tiger: 3, Leopard: 6, Rat: 1}
So I need to have 1st array
name :['Tiger', 'Leopard', 'Rat']
2nd array
count: [3, 6, 1]
Is it possible to obtain the same?
Sure, just use:
const names = Object.keys(animalCount);
const values = Object.values(animalCount);
As others have mentioned, you can use:
var name = Object.keys(animalCount);
var count = Object.values(animalCount);
If you, for some reason, needed to manipulate or change them while creating these arrays, you could also use a for i in animalCount loop, like so:
var animalCount = {Tiger: 3, Leopard: 6, Rat: 1};
var array1 = [];
var array2 = [];
for(i in animalCount){
if(animalCount.hasOwnProperty(i)){
array1.push(i);
array2.push(animalCount[i]);
}
}
console.log(array1);
console.log(array2);
How about
var name = [];
var count = [];
for(var prop in animalCount){
name.push(prop);
count.push(animalCount[prop]);
}
This way we're sure the order is preserved.
JS supports this natively.
var name = Object.keys(animalCount);
var count = Object.values(animalCount);
See:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys for Object.keys and
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values for Object.values
You could take a single loop and reduce the entries of the object by iterating the key/value array for pushing the items.
var animalCount = { Tiger: 3, Leopard: 6, Rat: 1 },
names = [],
count = [],
result = Object
.entries(animalCount)
.reduce((r, a) => (a.forEach((v, i) => r[i].push(v)), r), [names, count]);
console.log(names);
console.log(count);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I have a function using an array value represented as
markers[i]
How can I select all other values in an array except this one?
The purpose of this is to reset all other Google Maps images to their original state but highlight a new one by changing the image.
Use Array.prototype.splice to get an array of elements excluding this one.
This affects the array permanently, so if you don't want that, create a copy first.
var origArray = [0,1,2,3,4,5];
var cloneArray = origArray.slice();
var i = 3;
cloneArray.splice(i,1);
console.log(cloneArray.join("---"));
You can use ECMAScript 5 Array.prototype.filter:
var items = [1, 2, 3, 4, 5, 6];
var current = 2;
var itemsWithoutCurrent = items.filter(function(x) { return x !== current; });
There can be any comparison logics instead of x !== current. For example, you can compare object properties.
If you work with primitives, you can also create a custom function like except which will introduce this functionality:
Array.prototype.except = function(val) {
return this.filter(function(x) { return x !== val; });
};
// Usage example:
console.log([1, 2, 3, 4, 5, 6].except(2)); // 1, 3, 4, 5, 6
You can also use the second callback parameter in Filter:
const exceptIndex = 3;
const items = ['item1', 'item2', 'item3', 'item4', 'item5'];
const filteredItems = items.filter((value, index) => exceptIndex !== index);
You can use slice() Method
var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
var citrus = fruits.slice(1,3);
The slice() method returns the selected elements in an array, as a new array object.
This function will return a new array with all elements except the element at the specified index:
const everythingBut = (array, i) => { /*takes an array and an index as arguments*/
let notIArray = []; /*creates new empty array*/
let beforeI = array.slice(0, i); /*creates subarray of all elements before array[i]*/
let afterI = array.slice(i+1,); /*creates subarray of all elements after array[i]*/
notIArray = [...beforeI, ...afterI]; /*add elements before and after array[i] to empty array*/
return notIArray; /*returns new array with array[i] element excluded*/
};
For example:
let array = [1, 2, 4, 7, 9, 11, 2, 6]
everythingBut(array, 2); /*exclude array[2]*/
// -> [1, 2, 7, 9, 11, 2, 6]
Another way this can be done is by using filter and slice Array methods.
let array = [ 1, 2, 3, 4, 5, 6 ];
let leave = 2;
// method 1
console.log(array.filter((e,i) => i !== leave));
// logs [1, 2, 4, 5, 6];
//method 2
console.log([...array.slice(0, leave), ...array.slice(leave+1, array.length)]);
// logs [1, 2, 4, 5, 6];
You can combine Array.prototype.slice() and Array.prototype.concat() in using startingArray.slice(desiredStartIndex, exclusionIndex).concat(startingArray.slice(exclusionIndex+1)) to exclude the item whose index is exclusionIndex.
E.g., if you have a startingArray of [0, 1, 2] and want a desiredArray of [0, 2], then you can do as follows:
startingArray = [0, 1, 2];
desiredStartIndex = 0;
exclusionIndex = 1;
desiredEndIndex = 2;
desiredArray = startingArray.slice(desiredStartIndex,
exclusionIndex).concat(startingArray.slice(exclusionIndex+1));
With ECMAScript 5
const array = ['a', 'b', 'c'];
const removeAt = 1;
const newArray = [...array].splice(removeAt, 1);
I have two arrays. The first array contains some values while the second array contains indices of the values which should be removed from the first array. For example:
var valuesArr = new Array("v1","v2","v3","v4","v5");
var removeValFromIndex = new Array(0,2,4);
I want to remove the values present at indices 0,2,4 from valuesArr. I thought the native splice method might help so I came up with:
$.each(removeValFromIndex,function(index,value){
valuesArr.splice(value,1);
});
But it didn't work because after each splice, the indices of the values in valuesArr were different. I could solve this problem by using a temporary array and copying all values to the second array, but I was wondering if there are any native methods to which we can pass multiple indices at which to remove values from an array.
I would prefer a jQuery solution. (Not sure if I can use grep here)
There's always the plain old for loop:
var valuesArr = ["v1","v2","v3","v4","v5"],
removeValFromIndex = [0,2,4];
for (var i = removeValFromIndex.length -1; i >= 0; i--)
valuesArr.splice(removeValFromIndex[i],1);
Go through removeValFromIndex in reverse order and you can .splice() without messing up the indexes of the yet-to-be-removed items.
Note in the above I've used the array-literal syntax with square brackets to declare the two arrays. This is the recommended syntax because new Array() use is potentially confusing given that it responds differently depending on how many parameters you pass in.
EDIT: Just saw your comment on another answer about the array of indexes not necessarily being in any particular order. If that's the case just sort it into descending order before you start:
removeValFromIndex.sort(function(a,b){ return b - a; });
And follow that with whatever looping / $.each() / etc. method you like.
I suggest you use Array.prototype.filter
var valuesArr = ["v1","v2","v3","v4","v5"];
var removeValFrom = [0, 2, 4];
valuesArr = valuesArr.filter(function(value, index) {
return removeValFrom.indexOf(index) == -1;
})
Here is one that I use when not going with lodash/underscore:
while(IndexesToBeRemoved.length) {
elements.splice(IndexesToBeRemoved.pop(), 1);
}
Not in-place but can be done using grep and inArray functions of jQuery.
var arr = $.grep(valuesArr, function(n, i) {
return $.inArray(i, removeValFromIndex) ==-1;
});
alert(arr);//arr contains V2, V4
check this fiddle.
A simple and efficient (linear complexity) solution using filter and Set:
const valuesArr = ['v1', 'v2', 'v3', 'v4', 'v5'];
const removeValFromIndex = [0, 2, 4];
const indexSet = new Set(removeValFromIndex);
const arrayWithValuesRemoved = valuesArr.filter((value, i) => !indexSet.has(i));
console.log(arrayWithValuesRemoved);
The great advantage of that implementation is that the Set lookup operation (has function) takes a constant time, being faster than nevace's answer, for example.
This works well for me and work when deleting from an array of objects too:
var array = [
{ id: 1, name: 'bob', faveColor: 'blue' },
{ id: 2, name: 'jane', faveColor: 'red' },
{ id: 3, name: 'sam', faveColor: 'blue' }
];
// remove people that like blue
array.filter(x => x.faveColor === 'blue').forEach(x => array.splice(array.indexOf(x), 1));
There might be a shorter more effecient way to write this but this does work.
It feels necessary to post an answer with O(n) time :). The problem with the splice solution is that due to the underlying implementation of array being literally an array, each splice call will take O(n) time. This is most pronounced when we setup an example to exploit this behavior:
var n = 100
var xs = []
for(var i=0; i<n;i++)
xs.push(i)
var is = []
for(var i=n/2-1; i>=0;i--)
is.push(i)
This removes elements starting from the middle to the start, hence each remove forces the js engine to copy n/2 elements, we have (n/2)^2 copy operations in total which is quadratic.
The splice solution (assuming is is already sorted in decreasing order to get rid of overheads) goes like this:
for(var i=0; i<is.length; i++)
xs.splice(is[i], 1)
However, it is not hard to implement a linear time solution, by re-constructing the array from scratch, using a mask to see if we copy elements or not (sort will push this to O(n)log(n)). The following is such an implementation (not that mask is boolean inverted for speed):
var mask = new Array(xs.length)
for(var i=is.length - 1; i>=0; i--)
mask[is[i]] = true
var offset = 0
for(var i=0; i<xs.length; i++){
if(mask[i] === undefined){
xs[offset] = xs[i]
offset++
}
}
xs.length = offset
I ran this on jsperf.com and for even n=100 the splice method is a full 90% slower. For larger n this difference will be much greater.
I find this the most elegant solution:
const oldArray = [1, 2, 3, 4, 5]
const removeItems = [1, 3, 5]
const newArray = oldArray.filter((value) => {
return !removeItems.includes(value)
})
console.log(newArray)
output:
[2, 4]
or even shorter:
const newArray = oldArray.filter(v => !removeItems.includes(v))
function filtermethod(element, index, array) {
return removeValFromIndex.find(index)
}
var result = valuesArr.filter(filtermethod);
MDN reference is here
In pure JS you can loop through the array backwards, so splice() will not mess up indices of the elements next in the loop:
for (var i = arr.length - 1; i >= 0; i--) {
if ( yuck(arr[i]) ) {
arr.splice(i, 1);
}
}
A simple solution using ES5. This seems more appropriate for most applications nowadays, since many do no longer want to rely on jQuery etc.
When the indexes to be removed are sorted in ascending order:
var valuesArr = ["v1", "v2", "v3", "v4", "v5"];
var removeValFromIndex = [0, 2, 4]; // ascending
removeValFromIndex.reverse().forEach(function(index) {
valuesArr.splice(index, 1);
});
When the indexes to be removed are not sorted:
var valuesArr = ["v1", "v2", "v3", "v4", "v5"];
var removeValFromIndex = [2, 4, 0]; // unsorted
removeValFromIndex.sort(function(a, b) { return b - a; }).forEach(function(index) {
valuesArr.splice(index, 1);
});
Quick ES6 one liner:
const valuesArr = new Array("v1","v2","v3","v4","v5");
const removeValFromIndex = new Array(0,2,4);
const arrayWithValuesRemoved = valuesArr.filter((value, i) => removeValFromIndex.includes(i))
If you are using underscore.js, you can use _.filter() to solve your problem.
var valuesArr = new Array("v1","v2","v3","v4","v5");
var removeValFromIndex = new Array(0,2,4);
var filteredArr = _.filter(valuesArr, function(item, index){
return !_.contains(removeValFromIndex, index);
});
Additionally, if you are trying to remove items using a list of items instead of indexes, you can simply use _.without(), like so:
var valuesArr = new Array("v1","v2","v3","v4","v5");
var filteredArr = _.without(valuesArr, "V1", "V3");
Now filteredArr should be ["V2", "V4", "V5"]
You can correct your code by replacing removeValFromIndex with removeValFromIndex.reverse(). If that array is not guaranteed to use ascending order, you can instead use removeValFromIndex.sort(function(a, b) { return b - a }).
Here's one possibility:
valuesArr = removeValFromIndex.reduceRight(function (arr, it) {
arr.splice(it, 1);
return arr;
}, valuesArr.sort(function (a, b) { return b - a }));
Example on jsFiddle
MDN on Array.prototype.reduceRight
filter + indexOf (IE9+):
function removeMany(array, indexes) {
return array.filter(function(_, idx) {
return indexes.indexOf(idx) === -1;
});
});
Or with ES6 filter + find (Edge+):
function removeMany(array, indexes = []) {
return array.filter((_, idx) => indexes.indexOf(idx) === -1)
}
Here's a quickie.
function removeFromArray(arr, toRemove){
return arr.filter(item => toRemove.indexOf(item) === -1)
}
const arr1 = [1, 2, 3, 4, 5, 6, 7]
const arr2 = removeFromArray(arr1, [2, 4, 6]) // [1,3,5,7]
Try this
var valuesArr = new Array("v1", "v2", "v3", "v4", "v5");
console.info("Before valuesArr = " + valuesArr);
var removeValFromIndex = new Array(0, 2, 4);
valuesArr = valuesArr.filter((val, index) => {
return !removeValFromIndex.includes(index);
})
console.info("After valuesArr = " + valuesArr);
Sounds like Apply could be what you are looking for.
maybe something like this would work?
Array.prototype.splice.apply(valuesArray, removeValFromIndexes );
var valuesArr = new Array("v1","v2","v3","v4","v5");
var removeValFromIndex = new Array(0,2,4);
console.log(valuesArr)
let arr2 = [];
for (let i = 0; i < valuesArr.length; i++){
if ( //could also just imput this below instead of index value
valuesArr[i] !== valuesArr[0] && // "v1" <--
valuesArr[i] !== valuesArr[2] && // "v3" <--
valuesArr[i] !== valuesArr[4] // "v5" <--
){
arr2.push(valuesArr[i]);
}
}
console.log(arr2);
This works. However, you would make a new array in the process. Not sure if thats would you want or not, but technically it would be an array containing only the values you wanted.
You can try Lodash js library functions (_.forEach(), _.remove()). I was using this technique to remove multiple rows from the table.
let valuesArr = [
{id: 1, name: "dog"},
{id: 2, name: "cat"},
{id: 3, name: "rat"},
{id: 4, name: "bat"},
{id: 5, name: "pig"},
];
let removeValFromIndex = [
{id: 2, name: "cat"},
{id: 5, name: "pig"},
];
_.forEach(removeValFromIndex, (indi) => {
_.remove(valuesArr, (item) => {
return item.id === indi.id;
});
})
console.log(valuesArr)
/*[
{id: 1, name: "dog"},
{id: 3, name: "rat"},
{id: 4, name: "bat"},
];*/
Don't forget to clone (_.clone(valuesArr) or [...valuesArr]) before mutate your array
You could try and use delete array[index] This won't completely remove the element but rather sets the value to undefined.
removeValFromIndex.forEach(function(toRemoveIndex){
valuesArr.splice(toRemoveIndex,1);
});
For Multiple items or unique item:
I suggest you use Array.prototype.filter
Don't ever use indexOf if you already know the index!:
var valuesArr = ["v1","v2","v3","v4","v5"];
var removeValFrom = [0, 2, 4];
valuesArr = valuesArr.filter(function(value, index) {
return removeValFrom.indexOf(index) == -1;
}); // BIG O(N*m) where N is length of valuesArr and m is length removeValFrom
Do:
with Hashes... using Array.prototype.map
var valuesArr = ["v1","v2","v3","v4","v5"];
var removeValFrom = {};
([0, 2, 4]).map(x=>removeValFrom[x]=1); //bild the hash.
valuesArr = valuesArr.filter(function(value, index) {
return removeValFrom[index] == 1;
}); // BIG O(N) where N is valuesArr;
You could construct a Set from the array and then create an array from the set.
const array = [1, 1, 2, 3, 5, 5, 1];
const uniqueArray = [...new Set(array)];
console.log(uniqueArray); // Result: [1, 2, 3, 5]
Here is a sample of what I would like to do
function test(r){
var arr = ['d','e','f'];
r.push(arr);
/*
More Code
*/
return r;
}
var result = test(['a','b','c']);
alert(result.length);//I want this to alert 6
What I need to do is pass in an array and attach other arrays to the end of it and then return the array. Because of passing by reference I cannot use array.concat(array2);. Is there a way to do this without using something like a for loop to add the elements one by one. I tried something like r.push(arr.join()); but that did not work either. Also, I would like the option of having objects in the arrays so really the r.push(arr.join()); doesn't work very well.
>>> var x = [1, 2, 3], y = [4, 5, 6];
>>> x.push.apply(x, y) // or Array.prototype.push.apply(x, y)
>>> x
[1, 2, 3, 4, 5, 6]
Alternatively using destructuring you can now do this
//generate a new array
a=[...x,...y];
//or modify one of the original arrays
x.push(...y);
function test(r){
var _r = r.slice(0), // copy to new array reference
arr = ['d','e','f'];
_r = _r.concat(arr); // can use concat now
return _r;
}
var result = test(['a','b','c']);
alert(result.length); // 6
This is emulbreh's answer, I'm just posting the test I did to verify it.
All credit should go to emulbreh
// original array
var r = ['a','b','c'];
function test(r){
var arr = ['d','e','f'];
r.push.apply(r, arr);
/*
More Code
*/
return r;
}
var result = test( r );
console.log( r ); // ["a", "b", "c", "d", "e", "f"]
console.log( result === r ); // the returned array IS the original array but modified