JavaScript remove array - javascript

I tried doing delete weapons[i]; but even do when I do weapons.length I still get 1. Even though it should be 0. How do I definitely remove an array from weapons[] array?
I comb over the weapons array by doing this:
for (var i = 0, setsLen = weapons.length; i < setsLen; ++i ) {
var searchWeapon = weapons[i].split("|");
// console.log('['+i+'] >> Weapon ID: ' + searchWeapon[0] + ' | Y: ' + searchWeapon[1] + ' | X: ' + searchWeapon[2]);
if (searchWeapon[1] == Y && searchWeapon[2] == X) {
delete weapons[i];
}
}
and I store each array as 3|10|4 where 3 is weapon ID, 10 is Y, and 4 is X.

Check out the .splice method
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/splice
Using your example:
for (var i = 0, setsLen = weapons.length; i < setsLen; ++i ) {
var searchWeapon = weapons[i].split("|");
if (searchWeapon[1] == Y && searchWeapon[2] == X) {
weapons.splice(i,1);
}
}

Use splice
array.splice(index,howmany)

If your array doesn't need to be sorted, you could use array.pop() as it's extremely fast.
if(index == array.length-1) array.pop();
else array[index] = array.pop();
This method doesn't need to re-index everything after what you've splice()'d, so it remains quick whether your array has a length of 5 or 350,000.

Additional to the answers above:
you should walk the array from the end to the start, otherwise you'll miss elements inside the loop if a item has been removed.
Demo: http://jsfiddle.net/doktormolle/2f9Ye/

deleteing an array element leaves a hole behind with undefined left in the element's place. You probably want to use Array.splice.
var myArray = [1,2,3];
delete myArray[1]; // myArray is now [1, undefined, 3];
var myArray2 = [1,2,3];
myArray2.splice(1,1); // myArray2 is [1, 3]

To remove an element from an array use the splace method. Example:
var myArr = ["apple", "orange", "pear"];
alert(myArr.length); // 3
myArr.splice(1,1); // start at 1th index (i.e 2nd element), remove 1 element
alert(myArr.length); // 2
for (var i=0; i<myArr.length; i++) alert(myArr[i]); // "apple", "pear"

Related

Remove elements from array by type of element

I have an array and I want to remove all the string elements from it.
This is what I have so far. The result is not what I want since it returns only "bicycle"
Also, I am doing this in Test Complete so I need to have a main function that logs the result.
function ex06(){
var mailBox = "mailbox";
var twenty = 20;
var isItRaining = true;
var goat = "";
var stringsArray = ["bicycle", "pocket", 3, mailBox, twenty, isItRaining, goat];
var result = removeStrings();
Log.Message("stringsArray looks like this after the removal of all the string elements: " + result);
function removeStrings(){
var i;
var x
for(i = 0; i < stringsArray.length; i++){
if (typeof(stringsArray[i]) === 'string'){
x = stringsArray.splice(i, 1);
return x;
}
}
}
}
Version 1, with Array#filter
var a = [1, 2, "3", "4", true];
a = a.filter(function (e) {
return typeof e !== 'string';
});
document.write('<pre>' + JSON.stringify(a, 0, 4) + '</pre>');
Version 2, with Array#splice and running backwards.
var a = [1, 2, "3", "4", true],
i = a.length;
while (i--) {
if (typeof a[i] === 'string') {
a.splice(i, 1);
}
}
document.write('<pre>' + JSON.stringify(a, 0, 4) + '</pre>');
The Array.prototype.filter method is what you need:
var stringsArray = ["bicycle", "pocket", 3, mailBox, twenty, isItRaining, goat];
var result = stringsArray.filter(function(element) {
return typeof element !== 'string';
});
you need to reduce the counter variable and check the original array
try this simple example
var a = [1,2,"3", "4", true];
for( var counter = 0; counter < a.length; counter++)
{
if ( (typeof a[ counter ] ) == "string" )
{
a.splice(counter,1); counter--;
}
}
console.log(a); //output [1, 2, true]
try this code:
function ex06(){
var mailBox = "mailbox";
var twenty = 20;
var isItRaining = true;
var goat = "";
var stringsArray = ["bicycle", "pocket", 3, mailBox, twenty, isItRaining, goat];
var result = removeStrings();
Log.Message("stringsArray looks like this after the removal of all the string elements: " + result);
function removeStrings(){
var newarray = [];
var i;
var x
for(i = 0; i < stringsArray.length; i++){
if (typeof(stringsArray[i]) !== 'string'){
newarray.push(stringsArray[i]);
}
}
return newarray
}
}
JavaScript offers native methods to filter arrays, so that you can remove string elements more easily: Array.prototype.filter can make the process a lot easier (and prevents strange behaviours when using splice inside a loop).
function ex06(){
var mailBox = "mailbox";
var twenty = 20;
var isItRaining = true;
var goat = "";
var stringsArray = ["bicycle", "pocket", 3, mailBox, twenty, isItRaining, goat];
var result = removeStrings(stringsArray);
Log.Message("stringsArray looks like this after the removal of all the string elements: " + result);
function removeStrings(arrayWithString){
return arrayWithString.filter(function(item) {
return typeof item !== 'string'; // returns only items which are not strings
});
}
}
A small piece of advice: Pass in the array into your function instead of referencing it from the parent scope. This way you have a pure, reusable function (and no strange side effects you might not want).
I assume this is an exercise, and that's why you're not using Array#filter.
The problem is that you have your return x inside your for loop, so you return the first string you find.
You have at least three options:
Don't return anything, since removeStrings is modifying the original array. That one's easy: Just remove the return x; line.
Don't modify the original array; instead, create and return a new array with the strings left out. In that case, you'd start with x = [] before the loop, remove the splice call, and instead push any non-string onto x.
Modify the original array, and create and return a new array containing the strings you've removed. In that case, you'd remove return x from inside the loop, have x = [] before the loop, and push the entries you remove onto x. Then return x at the end.
In any of the places where you're modifying the original, note gurvinder372's point that when you remove an entry, you need to not increase the index counter, as you'll end up skipping the next entry.
I wouldn't do it the way he suggests, though; when I'm looping through an array modifying it, for isn't what I reach for, I reach for while:
i = 0;
while (i < stringsArray.length) {
if (typeof stringsArray[i] === 'string'){
stringsArray.splice(i, 1);
// We leave `i` alone here, because we need to process
// the new `stringsArray[i]` on the next pass
} else {
// Didn't remove this entry, move past it
++i;
}
}
Side note: typeof isn't a function, it's an operator, there's no need to put its operand in ():if (typeof stringsArray[i] === 'string'){

Get all elements of array with same (highest) occurrence

I have an array like [1,4,3,1,6,5,1,4,4]
Here Highest element frequency is 3 ,I need to select all elements from array that have 3 frequency like [1,4] in above example.
I have tried with this
var count = {},array=[1,4,3,1,6,5,1,4,4],
value;
for (var i = 0; i < array.length; i++) {
value = array[i];
if (value in count) {
count[value]++;
} else {
count[value] = 1;
}
}
console.log(count);
this will output array element with their frequency , now i need all elements that have highest frequency.
I'd approach this problem as follows.
First, write down how you think the problem can be solved IN ENGLISH, or something close to English (or your native language of course!). Write down each step. Start off with a high-level version, such as:
Count the frequency of each element in the input.
Find the highest frequency.
and so on. At this point, it's important that you don't get bogged down in implementation details. Your solution should be applicable to almost any programming language.
Next flesh out each step by adding substeps. For instance, you might write:
Find the highest frequency.
a. Assume the highest frequency is zero.
b. Examine each frequency. If it is higher than the current highest frqeuency, make it the current highest frequency.
Test your algorithm by executing it manually in your head.
Next, convert what you have written about into what is sometimes called pseudo-code. It is at this point that our algorithm starts to look a little bit like a computer program, but is still easily human-readable. We may now use variables to represent things. For instance, we could write "max_freq ← cur_freq". We can refer to arrays, and write loops.
Finally, convert your pseudo-code into JS. If all goes well, it should work the first time around!
In recent years, a lot of people are jumping right into JavaScript, without any exposure to how to think about algorithms, even simple ones. They imagine that somehow they need to be able to, or will magically get to the point where they can, conjure up JS out of thin air, like someone speaking in tongues. In fact, the best programmers do not instantly start writing array.reduce when confronted with a problem; they always go through the process--even if only in their heads--of thinking about the approach to the problem, and this is an approach well worth learning from.
If you do not acquire this skill, you will spend the rest of your career posting to SO each time you can't bend your mind around a problem.
A proposal with Array.prototype.reduce() for a temporary object count, Object.keys() for getting the keys of the temporary object, a Array.prototype.sort() method for ordering the count results and Array.prototype.filter() for getting only the top values with the most count.
Edit: Kudos #Xotic750, now the original values are returned.
var array = [1, 4, 3, 1, 6, 5, 1, 4, 4],
result = function () {
var temp = array.reduce(function (r, a, i) {
r[a] = r[a] || { count: 0, value: a };
r[a].count++;
return r;
}, {});
return Object.keys(temp).sort(function (a, b) {
return temp[b].count - temp[a].count;
}).filter(function (a, _, aa) {
return temp[aa[0]].count === temp[a].count;
}).map(function (a) {
return temp[a].value;
});
}();
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
Bonus with a different attempt
var array = [1, 4, 3, 1, 6, 5, 1, 4, 4],
result = array.reduce(function (r, a) {
r.some(function (b, i) {
var p = b.indexOf(a);
if (~p) {
b.splice(p, 1);
r[i + 1] = r[i + 1] || [];
r[i + 1].push(a);
return true;
}
}) || (
r[1] = r[1] || [],
r[1].push(a)
);
return r;
}, []).pop();
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
you can try this
var input = [1,4,3,1,6,5,1,4,4];
var output = {};
for ( var counter = 0; counter < input.length; counter++ )
{
if ( !output[ input[ counter ] ] )
{
output[ input[ counter ] ] = 0;
}
output[ input[ counter ] ]++;
}
var outputArr = [];
for (var key in output)
{
outputArr.push([key, output[key]])
}
outputArr = outputArr.sort(function(a, b) {return b[1] - a[1]})
now initial values of outputArr are the ones with highest frequency
Here is the fiddle
Check this updated fiddle (this will give the output you want)
var input = [1,4,3,1,6,5,1,4,4];
var output = {}; // this object holds the frequency of each value
for ( var counter = 0; counter < input.length; counter++ )
{
if ( !output[ input[ counter ] ] )
{
output[ input[ counter ] ] = 0; //initialized to 0 if value doesn't exists
}
output[ input[ counter ] ]++; //increment the value with each occurence
}
var outputArr = [];
var maxValue = 0;
for (var key in output)
{
if ( output[key] > maxValue )
{
maxValue = output[key]; //find out the max value
}
outputArr.push([key, output[key]])
}
var finalArr = []; //this array holds only those keys whose value is same as the highest value
for ( var counter = 0; counter < outputArr.length; counter++ )
{
if ( outputArr[ counter ][ 1 ] == maxValue )
{
finalArr.push( outputArr[ counter ][ 0 ] )
}
}
console.log( finalArr );
I would do something like this. It's not tested, but it's commented for helping you to understand my approach.
// Declare your array
var initial_array = [1,4,3,1,6,5,1,4,4];
// Declare an auxiliar counter
var counter = {};
// Loop over the array
initial_array.forEach(function(item){
// If the elements is already in counter, we increment the repetition counter.
if counter.hasOwnProperty(item){
counter[item] += 1;
// If the element is not in counter, we set the repetitions to one
}else{
counter[item] = 1;
}
});
// counter = {1 : 3, 4 : 3, 3 : 1, 6 : 1, 5 : 1}
// We move the object keys to an array (sorting it's more easy this way)
var sortable = [];
for (var element in counter)
sortable.push([element, counter[element]]);
// sortable = [ [1,3], [4,3], [3,1], [6,1], [5,1] ]
// Sort the list
sortable.sort(function(a, b) {return a[1] - b[1]})
// sortable = [ [1,3], [4,3], [3,1], [6,1], [5,1] ] sorted, in this case both are equals
// The elements in the firsts positions are the elements that you are looking for
// This auxiliar variable will help you to decide the biggest frequency (not the elements with it)
higgest = 0;
// Here you will append the results
results = [];
// You loop over the sorted list starting for the elements with more frequency
sortable.forEach(function(item){
// this condition works because we have sorted the list previously.
if(item[1] >= higgest){
higgest = item[1];
results.push(item[0]);
}
});
I'm very much with what #torazaburo had to say.
I'm also becoming a fan of ES6 as it creeps more and more into my daily browser. So, here is a solution using ES6 that is working in my browser now.
The shims are loaded to fix browser browser bugs and deficiencies, which is recommended in all environments.
'use strict';
// Your array of values.
const array = [1, 4, 3, 1, 6, 5, 1, 4, 4];
// An ES6 Map, for counting the frequencies of your values.
// Capable of distinguishing all unique values except `+0` and `-0`
// i.e. SameValueZero (see ES6 specification for explanation)
const frequencies = new Map();
// Loop through all the `values` of `array`
for (let item of array) {
// If item exists in frequencies increment the count or set the count to `1`
frequencies.set(item, frequencies.has(item) ? frequencies.get(item) + 1 : 1);
}
// Array to group the frequencies into list of `values`
const groups = [];
// Loop through the frequencies
for (let item of frequencies) {
// The `key` of the `entries` iterator is the value
const value = item[0];
// The `value` of the `entries` iterator is the frequency
const frequency = item[1];
// If the group exists then append the `value`,
// otherwise add a new group containing `value`
if (groups[frequency]) {
groups[frequency].push(value);
} else {
groups[frequency] = [value];
}
}
// The most frequent values are the last item of `groups`
const mostFrequent = groups.pop();
document.getElementById('out').textContent = JSON.stringify(mostFrequent);
console.log(mostFrequent);
<script src="https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.4.1/es5-shim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.34.0/es6-shim.js"></script>
<pre id="out"></pre>
you can do like this to find count occurrence each number
var array = [1, 4, 3, 1, 6, 5, 1, 4, 4];
var frequency = array.reduce(function(sum, num) {
if (sum[num]) {
sum[num] = sum[num] + 1;
} else {
sum[num] = 1;
}
return sum;
}, {});
console.log(frequency)
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>

Fill empty array

I need to iterate from 0 to 30, but I want to do this with help of forEach:
new Array(30).forEach(console.log.bind(console);
Of course this does not work, therefor I do:
new Array(30).join(',').split(',').forEach(console.log.bind(console));
Is there other ways to fill empty arrays?
Actually, there's a simple way to create a [0..N) (i.e., not including N) range:
var range0toN = Object.keys(Array.apply(0,Array(N)));
Apparently Object.keys part can be dropped if you only want to get a proper array of N elements.
Still, like others said, in this particular case it's probably better to use for loop instead.
if you want all of item have same value, do this
var arrLength = 4
var arrVal = 0
var newArr = [...new Array(arrLength)].map(x => arrVal);
// result will be [0, 0, 0, 0]
You could try using a for loop. new Array is not a best practise
var index, // we use that in the for loop
counter, // number of elements in array
myArray; // the array you want to fill
counter = 30;
myArray = [];
for (index = 0; index < counter; index += 1) {
myArray[index] = [];
/*
// alternative:
myArray.push([]);
// one-liner
for (index = 0; index < counter; index += 1) myArray.push([]);
*/
}
If you simply want to iterate, then use for loop like this
for (var i = 0; i < 30; i += 1) {
...
...
}
Actually, if you are looking for a way to create a range of numbers, then you can do
console.log(Array.apply(null, {length: 30}).map(Number.call, Number));
It will create numbers from 0 to 29. Source : Creating range in JavaScript - strange syntax
If you insist foreach
var data = [1, 2, 3];
data.forEach(function(x) {
console.log(x);
});

Delete zero values from Array with JavaScript

I have an array with name "ids" and some values like ['0','567','956','0','34']. Now I need to remove "0" values from this array.
ids.remove ("0"); is not working.
Here's a function that will remove elements of an array with a particular value that won't fail when two consecutive elements have the same value:
function removeElementsWithValue(arr, val) {
var i = arr.length;
while (i--) {
if (arr[i] === val) {
arr.splice(i, 1);
}
}
return arr;
}
var a = [1, 0, 0, 1];
removeElementsWithValue(a, 0);
console.log(a); // [1, 1]
In most browsers (except IE <= 8), you can use the filter() method of Array objects, although be aware that this does return you a new array:
a = a.filter(function(val) {
return val !== 0;
});
Use splice method in javascript. Try this function:
function removeElement(arrayName,arrayElement)
{
for(var i=0; i<arrayName.length;i++ )
{
if(arrayName[i]==arrayElement)
arrayName.splice(i,1);
}
}
Parameters are:
arrayName:- Name of the array.
arrayElement:- Element you want to remove from array
Here's one way to do it:
const array = ['0', '567', '956', '0', '34'];
const filtered = array.filter(Number);
console.log(filtered);
For non-trivial size arrays, it's still vastly quicker to build a new array than splice or filter.
var new_arr = [],
tmp;
for(var i=0, l=old_arr.length; i<l; i++)
{
tmp = old_arr[i];
if( tmp !== '0' )
{
new_arr.push( tmp );
}
}
If you do splice, iterate backwards!
For ES6 best practice standards:
let a = ['0','567','956','0','34'];
a = a.filter(val => val !== "0");
(note that your "id's" are strings inside array, so to check regardless of type you should write "!=")
Below code can solve your problem
for(var i=0; i<ids.length;i++ )
{
if(ids[i]=='0')
ids.splice(i,1);
}
ids.filter(function(x) {return Number(x);});
I believe, the shortest method is
var newList = ['0', '567', '956', '0', '34'].filter(cV => cV != "0")
You could always do,
listWithZeros = ['0', '567', '956', '0', '34']
newList = listWithZeros.filter(cv => cv != "0")
The newList contains your required list.
Explanation
Array.prototype.filter()
This method returns a new array created by filtering out items after testing a conditional function
It takes in one function with possibly 3 parameters.
Syntax:
Array.prototype.filter((currentValue, index, array) => { ... })
The parameters explain themselves.
Read more here.
The easy approach is using splice!!. But there's a problem, every time you remove an element your array size will constantly reduce. So the loop will skip 1 index the array size reduces.
This program will only remove every first zero.
// Wrong approach
let num = [1, 0, 0, 2, 0, 0, 3,];
for(let i=0; i<num.length; i++){
if(num[i]==0)
num.splice(i, 1);
}
console.log(num)
the output will be
[1,0,2,0,3]
So to remove all the zeros you should increase the index if you found the non-zero number.
let i = 0;
while(i<num.length){
if(num[i]==0){
num.splice(i,1);
}
else{
i++;
}
}
But there's a better way. Since changing the size of the array only affects the right side of the array. You can just traverse in reverse and splice.
for(let i=num.length-1; i>=0; i--){
if(num[i]===0)
num.splice(i,1);
}

Iterate through an array and return how many of each is present in jquery

So I have an array. The array has string values inside that can change each time:
var array = ['1','2','3','4','5'];
or sometimes:
var array = ['1','4','3','4','4'];
or even:
var array = ['1','3','3','4','4'];
How would I go about iterating through this array, figuring out which value is present the most and then displaying it. Also, how would I go about making it even smarter to understand that sometimes there is a tie between two values, as is the case in the last array above, and then displaying info notifying me that values "3" and "4" are tied... Or if there is no value that occurs more than once, thus displaying all values. Thoughts?
function findMostFrequent(array) {
// {
// "valueInTheArray": numberOfOccurances,
// ...
// }
var data = {};
// for each value in the array increment the number of
// occurences for that value. the or clause defaults it to 0.
$.each(array, function(i, val) {
data[val] = data[val]++ || 1;
});
var answer = null;
// for each value if the occurances is higher then to the counter.
// then set that as the counter.
$.each(data, function(key, val) {
if (val > data[answer]) answer = key;
}
return answer;
}
You need two loops. One to count how many times each value occured. And one to find which one occured the most.
Optionally if you want to handle multiple high values then replace the second loop with this.
var answer = [null];
// for each value if the occurances is equal then add it to the array
// else if the occurance is higher then the current highest occurance.
// then set that as the current array of values.
$.each(data, function(key, val) {
if (val === data[answer[0]]) {
answer.push(key);
} else if (val > data[answer[0]]) {
answer = [key];
}
}
return answer;
Try this:
var array = ['1','2','3', '3','4','5', '3', '4', '5', '5'],
l = array.length,
col = {},
current,
max = {cnt:0, values:[]};
while(l--){
current = array[l];
col[current] = (col[current] || 0) + 1;
if(col[current] > max.cnt){
max = {cnt:col[current], values: [current]};
}else if(col[current] === max.cnt){
max.values.push(current);
}
}
console.log(
max.cnt === 1 ?
'they are all different' :
max.values.join(',') + ' occured ' + max.cnt + ' times'
);
You probably want to use something like this:
var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
var counts = {};
for(var i = 0; i< arr.length; i++) {
var num = arr[i];
counts[num] = counts[num] ? counts[num]+1 : 1;
}
Now, you'll have an object that has a count of all the members in the array.
console.log(counts[5]); // logs '3'

Categories

Resources