I have module where I need to uncheck or check the data using checkbox. Now the problem is I need to slice the push value if the user uncheck it based on the target value. Currently when i try to console log the index it result -1 meaning: "it is not present" I will show you guys my sample code and sample attached image for the reference to make more detailed..
Code:
var array = [...this.state.checkboxVal];
console.log(e.target.value,"my index")
var index = array.indexOf(parseInt(e.target.value));
console.log(index);
if (index > -1) {
array.splice(index, 1);
await this.setState({ checkboxVal: array });
}
console.log(this.state.checkboxVal);
The Expected Output: The Index 1 should be remove
The problem is that you are storing an array of arrays so you are trying to compare number to array and apparently it will return -1. To solve this you can use findIndex function in the following way.
var value = parseInt(e.target.value);
var index = array.findIndex((element) => element[0] === value);
NOTE: Please use let and const these are latest way to define your variables.
The issue is that you are comparing incompatible types, "number" vs "array", so a match can never be found.
If you are simply wanting to remove an element from an array in state in React, using a Array.prototype.filter is a common pattern.
const targetValue = Number(e.target.value);
this.setState(prevState => ({
checkboxVal: prevState.checkboxVal.filter(([val]) => val !== targetValue),
}));
The filter callback ([val]) => val !== targetValue is taking the array element and uses destructuring assignment to get the value stored in index 0 and name it val and then return only the elements with a val not equal to the event's target value.
In your array, every element is an array (for example: [30, "2021-05-17"]). But you are now checking only the value whether it's present or not.
You have to check [30, "2021-05-17"] whether it's present or not.
Here's an example:
const arr = [[30, "2021-05-17"], [50, "2021-05-17"], [20, "2021-05-17"]];
const valueToDelete = 20;
const newArray = arr.filter(item => item[0] !== valueToDelete);
console.log(newArray);
In your case this would be:
var array = [...this.state.checkboxVal];
const newArray = array.filter(item => item[0] !== parseInt(e.target.value));
console.log(newArray);
this.setState({ checkboxVal: newArray });
Hope this will help you brother. Thank you. :)
Related
I work on an Angular project and I built an array.
Now I'd like to rename one of the items of the array. I found the way to rename the keys of an array but I still don't know how to do to apply this to its values.
Here is my array below.
I'd like to change 'valueC' by 'valueZ'.
myArray = ['valueA', 'valueB', 'valueC']
I tried the following code :
for (const k in this.myArray) {
if (k == "valueC") {
this.myArray[k] = "valueZ";
}
But it does not work.
Could you help me ?
Any help would be very appreciated, thanks.
Below are two possible methods!
const myArray = ['valueA', 'valueB', 'valueC']
//rename - if index known
myArray[2] = 'valueZ';
console.log('if index known', myArray);
//rename - if index not known
const foundIndex = myArray.findIndex(x => x === 'valueC');
if (foundIndex > -1) {
myArray[2] = 'valueZ';
}
console.log('if index not known', myArray);
Your code just needs a minor correction:
if (this.myArray[k] == "valueC")
Try this:
const myArray = ['valueA', 'valueB', 'valueC'];
for (const k in myArray) {
if (myArray[k] == "valueC") {
myArray[k] = "valueZ";
}
}
console.log(myArray);
You need to track the index, easy with a forEach
this.myArray.forEach((k, index) => {
if (k == "valueC") {
this.myArray[index] = "valueZ";
}
})
My prefered way :
Though, be sure to have the value "valueC" inside the array
otherwise indexOf will return a -1, provoquing an error
// without index control
this.myArray[this.myArray.indexOf("valueC")] = "valueZ";
// with index control
const index = this.myArray.indexOf("valueC")
if (index >= 0) {
this.myArray[index] = "valueZ";
}
Also note this for future usage :)
for (const k in array) : in that case k is the index of elements in array
for (const k of array) : in that case k is the value of elements in array
On top of all the other solutions here, another approach, and one I believe is better in that it gets you in the mindset of immutability, is to return a new object instead of modifying the current one.
Ex:
this.myArray = this.myArray.map(x => {
if(x !== 'valueC')
return x;
return 'valueZ';
});
So map here will return a new array object for us, in this case a string array given your current array is a string array. Another pattern in use here is only checking for the negative case. Instead of having if/else or a chain of them, we know that for all case that aren't 'valueC' we retain their original value and only valueC's value needs to change to valueZ
Given array:
const array = [{1: true},{2: false},{3: true},{}.....];
Filter the given array by only including objects with values of true.
Looking for the shortest solution.
const onlyTrue = array.filter((el, ind) => el[ind + 1] === true);
This will work only if indexes in array objects are ordered and starting from 1, as it is in your example.
Assumptions (based on what's in your example):
Each object in the array only has at least 1 property in it
The first property on each object is the one we care about
The property in each object is different every time
const array = [{1: true},{2: false},{3: true}];
const results = array.filter(item => Object.values(item)[0]);
If you want to avoid any false positives from truth-y values (see https://developer.mozilla.org/en-US/docs/Glossary/Truthy), then change the filter call to this instead:
const results = array.filter(item => Object.values(item)[0] === true);
const array = [{1: true},{2: false},{3: true}];
const array2 = [];
array.forEach(filterTrue);
function filterTrue(item){
for(x in item){
if(item[x]===true){
array2.push(item);
}
}
}
console.log(array2);
Hope this helps you.
I'd like to know IF a value is missing which one is missing.
Array1: You have these values at the moment
['cloud:user', 'cloud:admin']
Array2: You need to have these values in order to continue
['cloud:user', 'cloud:admin', 'organization:user']
Current method which returns true or false. But I'd like to know IF a value is missing which one is missing. For example: 'organization:user'. If nothing is missing return true.
let authorized = roles.every(role => currentResourcesResult.value.includes(role));
Just use filter method and check whether some of elements of arr1 is not equal to an element of an arr2:
const missingValues = arr2.filter(f => !arr1.some(s => s ==f));
An example:
let arr1 = ['cloud:user', 'cloud:admin']
let arr2 = ['cloud:user', 'cloud:admin', 'organization:user'];
const missingValues = arr2.filter(f => !arr1.some(s => s ==f));
console.log(missingValues);
You can check it by using Array.prototye.filter().
const domain = ['cloud:user', 'cloud:admin', 'organization:user'];
const data = ['cloud:user', 'cloud:admin'];
const notInDomain = domain.filter(item => data.indexOf(item) === -1);
if (notInDomain.length > 0) {
console.log('Some values are not in the domain set');
}
console.log(notInDomain);
Update
You can gain the same result by using includes instead of indexOf.
const notInDomain = domain.filter(item => !data.includes(item));
I am trying to remove a value by Index of the props array passed from another component.
[...this.props.data].splice([...this.props.data].indexOf(oldData), 1)
const {tableData, ...application} = oldData;
this.props.deleteData(application);
It deletes the data, but not just the selected value, but both values at the same time. I guess the problem is in the splice..indexOf
oldData :is the selected row that needs to be deleted.
You need to concat from 0 to index - 1 and from index + 1 to length - 1. So a simple this.props.data.slice(0, index).concat(this.props.data.slice(index) + 1) Should work.
Imo concat is easier to read and reason about because it does not mutate your array.
A filter could also work for you:
const filterIndex = target => (_, i) => i !== target;
newData = data.filter(filterIndex(index));
To use the filter version is pretty easy, two ways, depending on the use case.
1) Remove a specific index without leaving holes in the array
const target = this.props.data.indexOf(oldData);
const newData = this.props.data.filter((_, index) => index !== target);
2) Remove a specific value from the array (all its occurrences) without leaving holes in the array
const newData = this.props.data.filter((data) => data !== oldData);
Those two are slightly different as the first one will only remove the first occurrence of oldData and the second all
occurrences.
I'm new to ES6 and ReactJS. I need some help to filter out the results in array, in a way, where I can check if the index matches, only then call the function createOptions().
Actual code :
const newArr = items
.filter(this.isEligible(selectedIndex))
.filter((item, index) => this.createOptions(item, index, selectedItem));
Need something like(expected)):
const newArr = items
.filter(this.isEligible(selectedIndex))
.filter((item, selectedIndex) => selectedIndex || selectedIndex+ 2 ? this.createOptions(item, selectedIndex, selectedItem));
Here, I need to filter out the results when the index equals selectedIndex or selectedIndex+2, then call createOptions(item, index, selectedItem);
But, I'm getting some syntax error while trying to do that.
Could you please help me fix that?
If you want to access item at specific index in array, you don't need to filter that array. Just access it by bracket notation:
const itemAtIndex = items[selectedIndex]
const itemAtIndexPlusTwo = items[selectedIndex + 2]