How to pop an element in array in javascript? - javascript

How can I pop the random chosen out of the array?
var number = ["a", "b", "c"];
var random = number[Math.floor(Math.random()*number.length)];

use splice
var number = ["a", "b", "c"];
var random = Math.floor(Math.random()*number.length);
console.log(number[random], ' is chosen');
var taken = number.splice(random, 1);
console.log('after removed, ', number);
console.log('number taken, ', taken);

Use splice and the random number as the index.
number.splice(random, 1);

You can use Splice to remove a certain number of items from an array. This method will altar the original array and return the values removed.
The first argument in the Splice method is the starting point. The second argument is the number of items to remove.
Example:
// 0 1 2
var array = ["a", "b", "c"];
var splicedItem = array.splice(1,1);
// The array variable now equals ["a", "c"]
console.log("New Array Value: " + array);
// And the method returned the removed item "b"
console.log("Spliced Item: " + splicedItem);
You can also use a negative number in the first argument to begin counting backwards from the end of the Array.
Example:
// -6 -5 -4 -3 -2 -1
var array2 = ["a", "b", "c", "d", "e", "f"];
var splicedItem2 = array2.splice(-3, 2);
// The array2 variable now equals ["a", "b", "c", "f"]
console.log("New Array Value: " + array2);
// The values removed were "d" and "e"
console.log("Spliced Item: " + splicedItem2);
You can even insert new items into the Array by including additional arguments. You also don't need to return the spliced items to a new variable if you don't want to.
Example:
var array3 = ["a", "b", "c", "d", "e", "f"];
array3.splice(2, 2, "Pink", "Mangoes");
// The array3 value is now ["a", "b", "Pink", "Mangoes", "e", "f"]
console.log("New Array Value: " + array3);

Related

JavaScript function to get the number of occurrences of each letter in specified string

I am new to JavaScript. Can anyone tell me why counter = 1 is added in following code ?
function count(string) {
let string1 = string.split("").sort().join("");
let counter = 1;
for (let i = 0; i < string1.length; i++) {
if (string1[i] == string1[i + 1]) {
counter++;
} else {
console.log(string1[i] + " " + counter);
counter = 1;//-----------> this one
}
}
}
count("amanpreetsaingh");
You sort the whole characters in the string and start from left to right.
If your string is amanpreetsaingh, it becomes aaaeeghimnnprts.
Now what you do is keep a counter=1 starting from index 0. And check for every letter you check if it is equal to the next one, if yes then we are counting for the same letter and increase counter (like in case of the first two as). Once we reach the last a, our next letter (e) is not the same as our current letter, so we log our current value and reset count.
you can simply use reduce function:
reduce it's an array method so make sure to transform your string into array by using split(""):
text.split("") // ["a", "a", "a", "a", "b", "b", "b", "c", "c", "c", "c", "c", "c", "c", "d", "d", "d", "d", "d", "d", "d"]
then apply reduce on the result array :
text.split("").reduce((acc, c) => {
const counter = acc[c] || 0;
return {
...acc,
[c]: counter + 1,
};
}, {}); // { a: 4, b: 3, c: 6, d: 5 }
I suggest you watch this series of videos about the arrays method from ack Herrington: https://youtu.be/NaJI7RkSPx8

How do i write a function that iterates through a list of sets of elements of varied amounts extracting sequential arrays of 4

i have a long list of sets of elements of varied amounts . For each line, I want to extract only those sets which have 4 elements or more and push them into a separate array . If the set has more than 4 elements , I want to extract each set of 4 elements within them. for instance
a,b,c
a,b,c,d
d,b,c,a
a,b,d,c,a,d
a,d
returns
result = [ [a,b,c,d], [d,b,c,a] , [a,b,d,c], [b,d,c,a], [d,c,a,d] ]
notice that the second to the last set of elements produces 3 arrays at the end of the result array.
How would i write a JS or Ruby function/method to return this kind of result ??
A Ruby solution: first select the arrays which are big enough, then put all consecutive series of 4 elements in the result.
input = [['a','b','c'], ['a','b','c','d'], ['d','b','c','a'], ['a','b','d','c','a','d'], ['a','d']]
p input.select{|ar| ar.size >= 4}.flat_map{|ar| ar.each_cons(4).to_a }
# =>[["a", "b", "c", "d"], ["d", "b", "c", "a"], ["a", "b", "d", "c"], ["b", "d", "c", "a"], ["d", "c", "a", "d"]]
Here is the solution, I looked at the array if it is length of 4 I just pushed it into the result if it is more then 4 then I iterated over it to push every one instance of 4, I hope this is what you wanted.
const input = [['a','b','c'], ['a','b','c','d'], ['d','b','c','a'], ['a','b','d','c','a','d'], ['a','d']]
const result = []
input.forEach(arr => {
if (arr.length === 4) {
result.push(arr)
} else if (arr.length > 4) {
for (let i = 0; i < arr.length - 3; i++) {
result.push(arr.slice(0 + i, 4 + i))
}
}
})
console.log('result = ', result)
//result = [ [a,b,c,d], [d,b,c,a] , [a,b,d,c], [b,d,c,a], [d,c,a,d] ]
Another Ruby solution.
input = [['a','b','c'], ['a','b','c','d'], ['d','b','c','a'],
['a','b','d','c','a','d'], ['a','d']]
input.each_with_object([]) do |a,arr|
a.each_cons(4) { |a4| arr << a4 } if a.size > 3
end
#=> [["a", "b", "c", "d"], ["d", "b", "c", "a"], ["a", "b", "d", "c"],
# ["b", "d", "c", "a"], ["d", "c", "a", "d"]]
See Enumerable#each_cons.

Converting number string into number in an array

I have an array containing single strings. e.g. ["a", "b", "3", "c"];
However, I need any number in this array to be a number and not a string.
Result would be ["a", "b", 3, "c"]; so I could then run a regex and get all numbers out of the array.
Hope this is clear enough.
You can use map and isNaN
let a = ["a", "b", "3", "c"];
let final = a.map(val => !isNaN(val) ? +val : val)
console.log(final)
You could use + since NaN is evaluated as false if the value is not a number, so (+e || e) returns a number or the original value:
const array = ["a", "b", "3", "c"];
const res = array.map(e=>(+e || e));
console.log(res);

How to remove extra occurrences of a reference array

let's assume that we have two arrays like these:
let s1 =  ["A", "B", "C", "D", "B"] // Note: "B" has been occurred 2 times
let s2 = ["A", "B", "C", "D", "B", "A", "X", "Y"] // // Note: "B" has been occurred 2 times just like s1 but we have another occurrence for "A"
I want to create a new array (let s3) based on these two arrays with this rule that we'll remove the element(s) with occurrences more than the same element's occurrence in array s1
so the s3 array would be like this:
let s3 = ["A", "B", "C", "D", "B", "X", "Y"] // we just removed "A" cause it occurred more than "A" occurances in s1
Note that we want anything else ("X", "Y"). we just want to handle the extra occurrences.
so far I can find the index of repeated occurrences like this but I can't find a way to compare each occurrence to see if it is an extra one or not (complicated):
let s1 =  ["A", "B", "C", "D", "B"]
let s2 = ["A", "B", "C", "D", "B", "A", "X", "Y"]
var s3 = [];
for (let i = 0; i < s2.length; i++) {
for (let j = 0; j < s1.length; j++) {
if (s2[i] === s1[j]) {
s3.push(i);
break;
}
}
}
console.log(s3)
My English is poor and I don't know if I could explain the issue or not!
Note: I can simply use s3 = [...new Set(s2)] to remove repeated elements but I want something else.
Since you want to keep everything originally in s1 but only add items from s2 if they aren't already in you can initially set s3 to s1. Then loop over s2 and if s1 does not have the value then push it into s3.
const s1 = ["A", "B", "C", "D", "B"];
const s2 = ["A", "B", "C", "D", "B", "A", "X", "Y"];
const s3 = [...s1];
s2.forEach(d => {
if (!s1.includes(d)) s3.push(d);
});
console.log(s3);
You can use Map and filter
First Map the array1 to [key, value] format
Iterate over second array, if it's found in Map and value is grater than zero return true else return false,
If it is not found return true
let s1 =  ["A", "B", "C", "D", "B"]
let s2 = ["A", "B", "C", "D", "B", "A", "X", "Y"]
let map = new Map()
s1.forEach(v=>{
if(map.has(v)){
map.set(v,map.get(v)+1)
} else{
map.set(v,1)
}
})
let final = s2.filter(val=>{
if(map.has(val)){
if(map.get(val)){
map.set(val, map.get(val)-1)
return true
}
return false
}
return true
})
console.log(final)
You could count the values of the first set and return the values for a given count or if not known then all items.
var s1 = ["A", "B", "C", "D", "B"],
s2 = ["A", "B", "C", "D", "B", "A", "X", "Y"],
count = s1.reduce((m, v) => m.set(v, (m.get(v) || 0) + 1), new Map),
s3 = s2.filter(v => count.get(v) ? count.set(v, count.get(v) - 1) : !count.has(v));
console.log(...s3);

Pull array values associated with bitmask

I have a simple bitmask, 3 ("011" in base 2) which denotes that I should extract array[0] and array[1] but not array[2]
What is an efficient way to do this?
Ultimately, I'm generating a new array with values that passed a .filter
Something like this:
var bitmask = 37, // "100101"
array = ["a", "b", "c", "d", "e", "f"];
var array2 = array.filter((value, index) => {
// do something with bitmask and index to return true
});
// array2 should be ["a", "c", "f"];
Expanding on your original example you can do this:
var bitmask = 37, // "100101"
array = ["a", "b", "c", "d", "e", "f"];
var array2 = array.filter((value, index) => {
// do something with bitmask and index to return true
return bitmask & (1 << index);
});
// array2 should be ["a", "c", "f"];
console.log(array2);
var bitmask = 5, idx=0;
// Loop till bitmask reach 0, works when bitmask >= 0
// If you want to sure instead of implicit type converting (from number to boolean)
// Just change it to while(bitmask >= 0)
while(bitmask){
// If the rightmost bit is 1, take the array[index]
if(bitmask & 1) console.log("take arr["+idx+"]");
// Shift right by 1 bit, say 5 = 101, this will make the number become 2 = 10
bitmask>>=1;
// Increase the index
idx++;
}
Using your own example, here is the code works:
var bitmask = 37, // "100101"
array = ["a", "b", "c", "d", "e", "f"],
idx = 0;
var array2 = [];
while(bitmask){
if(bitmask & 1) array2.push(array[idx]);
bitmask>>=1;
idx++;
}
Simply use some bit operation to loop it. As it is looping bit by bit, I think it is the fastest you can get
One way to do this is cast your number into a binary string, then check if the index of the bitmask is "1" inside your filter.
var bitmask = (37).toString(2), // "100101"
array = ["a", "b", "c", "d", "e", "f"];
var array2 = array.filter((value, index) => {
if(bitmask[index] == "1") return value;
});
console.log(array2);

Categories