How to propertly delete Stings from array in JS? [duplicate] - javascript

This question already has answers here:
Looping through array and removing items, without breaking for loop
(17 answers)
Closed 2 years ago.
So i'm trying to write a function that deletes all the strings from array.
It works, but deletes only half of them, why?
let list = [1,2,'a','b', 'c', 'd', 'e'];
function filter_list(l) {
for (let i = 0; i < l.length; i++) {
if(typeof l[i] === 'string') {
l.splice(l.indexOf(l[i]), 1);
}
}
console.log(l)
}
filter_list(list)

Use Array.prototype.filter() to return a filtered subset Array, and typeof to check the operand type:
const list = [1,2,'a','b', 'c', 'd', 'e'];
const nums = list.filter(x => typeof x !== "string");
console.log(nums)

const list = [1,2,'a','b', 'c', 'd', 'e'];
const nums = list.filter(i => typeof i !== "string");
console.log(nums)
This checks each element and excludes those of type string.

Related

Comparing two arrays and returning valid and misplaced elements

I wanted to make a simple game for my first project but I've encountered some problems with the logic behind it.
The game should compare two arrays, one of which stores user input and the other which is randomly generated. Both arrays have the length of n (let's say n=3) and accept n unique characters as their values. Let's say that the user input is ['A','A', 'B'] and that the winning combination is ['B', 'A', 'C']. The win condition is simple, all three elements from the user input array must be valid. An element is valid if both it's value and index correspond to the element in the second array.
Checking this is simple enough:
for (let i = 0; i<arr1.length; i++) {
for (let j = 0; j<arr1.length; j++){
if (arr[i] === arr1[j] && getIndices(arr[i], arr1[j]) === true){
valid ++;
}
However, I also want to keep track of misplaced elements, where arr[i] matches the value of arr[j] but the equality check on their indices returns false. Here's the problem, if I were to put this inside an else statement, and compare ['A', 'B', 'A'] to ['A', 'C', 'C'] it would return 1 valid as it should, but also 1 misplaced which is incorrect because 'A' only appears once in the second array. How would you set up the statement to avoid this?
I'm quite new to this so I haven't tried much.
If the input value and the win condition has the same length, you don't need two for loop. And name your variables correctly: inputs and condition.
var points = 0
var misplacedElements = []
for (let i = 0; i<inputs.length; i++) {
//findIndex returns index of the element on the condition array
//If element don't exist returns -1
const indexOfInput = condition.findIndex(e=> e === inputs[i])
if(indexOfInput != -1){
//Element contains but might not be on the same index
if(indexOfInput == i){
//On the same index so give a point
points++
}else{
//Hold the index or the element depends to your need
misplacedElements.push( i )
}
}
You can ask if you don't understand.
This is the JS way.
const userList = ['A', 'B', 'C'];
const winList = ['A', 'B', 'A'];
const scoreCalculator = ({ user, win }) => {
let points = 0;
user.forEach((value, index) => {
if (value === win[index]) {
points++;
}
});
return points;
}
console.log(scoreCalculator({user: userList, win: winList}));
The cost will be O(n).
With normal for execution.
const userList = ['A', 'B', 'C'];
const winList = ['A', 'B', 'A'];
const scoreCalculator = ({ user, win }) => {
let points = 0;
for(let i = 0; user.list; i++) {
if (user[i] === win[i]) {
points++;
}
});
return points;
}
console.log(scoreCalculator({user: userList, win: winList}));
As you can see, Array.prototype.forEach() its work like normal for.

Remove all non numbers without creating new array [duplicate]

This question already has answers here:
Looping through array and removing items, without breaking for loop
(17 answers)
Closed 1 year ago.
I just did a coding challenge where I had to remove all non numberic items from an array without creating a new array which means no map or filter.
I didn't do that great because I was trying to splice but I'd lose my index.
What is a nice way of doing this?
const filterNums = (nums) => {
for (let item in nums) {
if (typeof nums[item] !== 'number') {
// Remove item
}
}
return nums;
};
console.log(filterNums([1, 'a', 2, 'b', true]));
Use an indexed-based loop instead, starting at the end of the array.
const filterNums = (nums) => {
for (let i = nums.length - 1; i >= 0; i--) {
if (typeof nums[i] !== 'number') {
nums.splice(i, 1);
}
}
return nums;
};
console.log(filterNums([1, 'a', 2, 'b', true]));

How to store old array and compare it to the new updated array useRef and useEffect

Currently I am building a Hanging man game, where I want to store the old array length and compare it to the new array length. I know that useRef is the stuff I need to get this done. Could someone help me with this.
useEffect(() => {
const checkLetter = (event) => {
let letter = String.fromCharCode(event.keyCode).toLowerCase();
if(event.keyCode >= 65 && event.keyCode <= 90) {
setCount(count + 1);
setGuessed(prev => {
const next = [...prev, letter]
counter(next);
return next;
});
}
}
document.addEventListener('keydown', checkLetter);
return () => {
document.removeEventListener('keydown', checkLetter);
}
}, [guessed, count]);
const counter = (letterArray) => {
let oldArray = letterArray.filter((v, i) => letterArray.indexOf(v) === i);
// currently oldArray outputs for instance ['a', 'b', 'c'];
// if someone clicks on a new letter for instance 'd', the new updated array becomes ['a', 'b', 'c', 'd']. And if I want to compare the old array with new updated array for instance like: oldArray !== newUpdatedArray, it returns true.
}
if current old array is ['a', 'b', 'c'] and you recently clicked on letter d, the new updated array becomes ['a', 'b', 'c', 'd']. And then i want to compare ['a', 'b', 'c'] !== ['a', 'b', 'c', 'd'];
Arrays will be compared by refs, so even [] === [] will always return false. You probably need to compare by values. If you always adds letters to the end of array, you probably can check by just:
const compare = (array1, array2) => {
if (array1.length !== array2.length) {
return false;
}
return array1.every(
(item, index) => item === array2[index]
);
}
If you want compare only values and you don't care about order:
const isIn = (array1, array2) => {
return array1.every(
return array2.includes(item);
);
}
const compare = (array1, array2) => isIn(array1, array2) || isIn(array2, array1);
You can also use lodash.difference() for that.
You can simply compare arrays length
const compareArr = (oldArr, newArr) => oldArr.length === newArr.length
It will return true if array has same length as before and false if length has changed
Hope it helps

Replace the same character in string with an array, but on every occurence use next entry [duplicate]

This question already has answers here:
How to replace question marks inside a string with the values of an array?
(5 answers)
Closed 3 years ago.
Replace character with an array to get the desired result, but on every occurence use the next array entry.
Do you have any ideas on how to get this?
var str = 'a ? c ? e ?';
var arr = ['b', 'd', 'f'];
var result_str = 'a b c d e f'; //desired outcome
//I was thinking about something like
result_str = 'a ? c ? e ?'.split('?').join(['b', 'd', 'f']);
//of course it just joins the array before replaceing, so the result is
result_str = "a b,d,f c b,d,f e b,d,f"
You could replace the ? with a function which takes an item of the array.
var string = 'a ? c ? e ?',
array = ['b', 'd', 'f'],
result = string.replace(/\?/g, (i => _ => array[i++])(0));
console.log(result);
With shift as callback
var string = 'a ? c ? e ?',
array = ['b', 'd', 'f'],
fn = Array.prototype.shift.bind(array),
result = string.replace(/\?/g, fn);
console.log(result);
You can split the string with ? delimiter and then then use filter to remove empty string. Then use map to return an array of character and inside its call back use the index to retrieve element from the second array. Then use join to create the string
var str = 'a ? c ? e ?';
var arr = ['b', 'd', 'f'];
let newStr = str.split('?')
.filter(item => item !== "")
.map((item, index) => item + arr[index])
.join(' ');
console.log(newStr)

Function to convert an Array to an Associative array [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Convert flat array [k1,v1,k2,v2] to object {k1:v1,k2:v2} in JavaScript?
I want to convert an array to an associative array in JavaScript.
For example, given the following input,
var a = ['a', 'b', 'c', 'd'];
I want to get the next associative array as output:
{'a' : 'b', 'c' : 'd'}
How can I do that?
Using .forEach:
var a = ['a', 'b', 'c', 'd'];
var obj_a = {};
a.forEach(function(val, i) {
if (i % 2 === 1) return; // Skip all even elements (= odd indexes)
obj_a[val] = a[i + 1]; // Assign the next element as a value of the object,
// using the current value as key
});
// Test output:
JSON.stringify(obj_a); // {"a":"b","c":"d"}
Try the following:
var obj = {};
for (var i = 0, length = a.length; i < length; i += 2) {
obj[a[i]] = a[i+1];
}
There is no such thing as an associative array, they're called Objects but do pretty much the same :-)
Here's how you would do the conversion
var obj = {}; // "associative array" or Object
var a = ['a', 'b', 'c', 'd'];
for(index in a) {
if (index % 2 == 0) {
var key = a[index];
var val = a[index+1];
obj[key] = val;
}
}

Categories