Assign value to variable from object array with template literals? - javascript

I am trying to dynamically assign data to a variable based on object array values.
I am going to present a simplified data structure:
const data = [{"age":25,"name":"Michael"},{"age":20,"name":"Lara"}]
const data2 = [{"age":26,"name":"Sarah"},{"age":21,"name":"David"}]
I want to assign values to variables. For example, I know this works:
const arr = 'data'
const zero = '0'
const a = 'age'
const test = `${data[zero][a]}`
console.log(test) // returns 25
But can I assign it dynamically(maybe nested template literal)?
const test = `${arr[zero][a]}`
console.log(test) // does not work, because arr is a string
const test = `${${arr}[zero][a]}`
console.log(test) // does not work
Is there any way to achieve this?
Thank you in advance!
Edit:
I overthought the solution(tried to be fancy with template literals).
To solve it, thanks to the input from ggorlen I changed the way my data was stored. That way, it was way easier to access the data dynamically. The solution was fairly similar to the answer from Sowmen Rahman.
I was trying too hard to think about solving a problem in a specific way, when a different approach was more sensible!

Something like this won't be possible in the way you're suggesting. Strings can't be dynamically converted to variable names by itself, however if you stored your variables in a dictionary or map object, you can use the subscript operator [] to achieve the task.
const data = [{"age":25,"name":"Michael"},{"age":20,"name":"Lara"}]
const data2 = [{"age":26,"name":"Sarah"},{"age":21,"name":"David"}]
const rootObject = {
data: data,
data2: data2
}
const arr = 'data'
const zero = '0'
const a = 'age'
const test = `${rootObject[arr][zero][a]}`
console.log(test) // outputs 25

Related

JavaScript Objects filtering out specific property names

I am creating a filter for a diagram. Whenever a filter is clicked it should remove that category from the diagram. The api call returns an object with names. let’s say the object returns 40 items and I want to filter 5 out by name. What is the best way to approach this?.
I tried to manually type the property names into an array and run the .filter on my object like below. However it returns the entire object unfiltered.
filterDiagram() {
Const array = [“all the names of the properties I want to filter out”]
carbonates = array.forEach(x) => {console.log(x)}
Const filterCat = data.filter (io =>
io.name !== carbonates)
}
Let's say, the array consists of all the names/categories you want to take out.
const toBetakenOut = ['fruits','salts', 'etc' ]
// Please make sure they are not 1 string but rather comma-separated values.
You can filter the API data by using the filter function on the data,to remove objects with names that are within toBetakenOut.
const filterCat = data.filter (io => !toBetakenOut.includes(io.name))
function filterDiagram(){
const dontWantsArray = [/*all of the things you dont want*/];
// Outputs an array of keys
const filteredKeys = Object.keys(yourJSObject)
.filter(key => !dontWantsArray.includes(key));
// After you found the keys you can get the values to another array by keys
const filteredValues = filteredKeys.map(key => yourJSObject[key]);
}

How to get key value in this case {Java Script}

Hi so what iam trying to achieve is basically is simple.Iam try to get only the object key's value from the given array
so this is my example array
[{'aaa': '11','text':'hello'},{'aaa': '12','text':'bye'}]
iam expecting a output of something like this
[11,12]
where iam getting the data of the aaa key only
This will do what you want, but the order could well change between different javascript implementations
const input = [{'aaa': '11','text':'hello'},{'bbb': '12','text':'bye'}]
const output = input.map(x => Object.values(x)[0]);
console.log(output)
I note you updated the quesrtion to have both the same first key - if you're looking for aaa value from all elements this is much simpler
const input = [{'aaa': '11','text':'hello'},{'aaa': '12','text':'bye'}]
const output = input.map(x => x.aaa);
console.log(output)
const o = [{'aaa': '11','text':'hello'},{'aaa': '12','text':'bye'}]
const filtered = o.map(i => +i.aaa)
console.log(filtered)
The JSON path if you convert this into a JavaScript Object Notation format (as JSON).
0.aaa = 11
1.bbb = 12

How to add and update objects into array of objects?

I am trying to dynamically add an object to an array of objects, I have been trying to Destructuring the main object but it adds a number to the end of the parent array. This is what I have:
const [data, setData] = useState ([
{
_id:1,
firstName:'Leo',
lastName:'Miller',
telephone:'+569273829',
mail:'leo.miller#gmail.com',
work:[
{_id:1, startWorkDate:'01/01/2015', endWorkDate:'01/02/2017', work:'description...'},
{_id:2, startWorkDate:'01/01/2018', endWorkDate:'01/02/2020', work:'description...'}
]
}];
I generate dynamically this object:
const value = {_id:3, startWorkDate:'01/01/2018', endWorkDate:'01/02/2020', work:'description...'}
I need to add it into data.work and after that update only the description of work._id[3]
I try with this function
const addNewWork = (value) => {
let copyData = [...data, data[0].workExperience.push(value)]
return setData(copyData)
}
but for some reason doesn't add correctly the object. Help please!
You have an array and not an object. Your statement
let copyData = [...data, data[0].workExperience.push(value)]
is doing two things:
mutating the state by doing push(). Which is not the react way.
creating a new array. Also adding a new item to the array, but that is the new length of data[0].workExperience.
The return value of Array.prototoype.push is:
The new length property of the object upon which the method was called.
What you have to do is:
Make a copy of the array. Can use ... (spread operator) here.
Make a copy of the array object you want (first index). Try to add the object to its specific property workExperience.
const addNewWork = (value) => {
let newData = [...data];
let newWorkExperienceArray =
[...data[0].workExperience,value];
let newDataFirstObject = {...data[0], workExperience : newWorkExperienceArray};
newData[0] = newDataFirstObject;
return setData(newData)
}
You can also update the property. I didn't find the relevant code in your question as to what I have to update so I didn't update anything in the third workExperience object.
EDIT: It seems in your code the property name is work and not workExperience. Please confirm. The above code uses workExperience, you can replace it by work if that is the case
You can do this with this simple function:
const addNewWork = (value) => {
let updatedObj = data[0];
updatedObj.work.push(value)
// updates your object each time
let copyData = [updatedObj]
// adds a new object for each call
// let copyData = [...data, updatedObj]
return setData(copyData)
}
Now it updates the object in your state. If you want to add a new object for each call just uncomment let copyData = [...data, updatedObj] and comment out let copyData = [updatedObj]
When you set state for array your setter is a quite bite different
setData(prevData => [...prevData, newItem]) // to add a single item to array
setData(prevData => newArray) // to replace entire array

looking to remove duplicates from an array with key value pair

I have duplicate values looks like as shown in below figure
I have used below code but its only giving the names like as ashare1 guideline2and i am looking for id as well.
please find the below code currently i have used
const optionMap0 = [
...new Set(libraryEquipment.map(e => e.equipmentSource.name)),
{
id: '1d037be564c548eebe71db4e45e26cf7',
name: 'None',
},
];
Could any one please suggest any idea on how to get distinct values from the above array of objects.
many thanks in advance
You can convert it to an object, with the key as the name, and the value as the object itself, and then use Object.values() to get the objects.
const obj = {};
libraryEquipment.forEach(e => obj[e.equipmentSource.name] = e.equipmentSource);
const optionMap0 = Object.values(obj);
Unlike set, if you have more than one object with the same name, it will keep the last one. You can check before adding the object so it will use the first object with the same name, like so:
const obj = {};
libraryEquipment.forEach(e => {
if (!obj[e.equipmentSource.name])
obj[e.equipmentSource.name] = e.equipmentSource'
});
const optionMap0 = Object.values(obj);

Creating a two-dimensional object from a string of values

In JavaScript, how would I create a two-dimensional object from a string of values, in which the first value would be the name, the last is the content, and all other values in between are properties?
For example, I have a string "capitals,Asia,China,Beijing" and I want the code to split this string into four values and create an object capitals["Asia","China"] = "Beijing";.
How could I do that?
In a complete code piece that would look like this:
<script>
Values = "capitals,Asia,China,Beijing";
Values = Values.split(",");
alert(capitals["Asia","China"]);
</script>
I want the alert box to show me the word Beijing.
How could I do that?
JavaScript does not have two-dimensional arrays or objects that you can access using array[index1, index2] as in some other languages. To do this, you have to use nested objects/arrays, such as
capitals["Asian"]["China"]
To create these, you can do something like:
function makeEntry(obj, str) {
const parts = str.split(','); // array of comma-delimited values
const value = parts.pop(); // final value ("Beijing")
const final = parts.pop(); // final property ("China")
// Find nested property, creating empty object if not there.
for (let i = 0; i < parts.length; i++) {
const part = parts[i];
if (!(parts in obj)) obj[part] = {};
obj = obj[part];
}
// Set final value.
obj[final] = value;
}
const data = {};
makeEntry(data, "capitals,Asian,China,Beijing");
console.log(data);
console.log(data.capitals["Asian"]["China"]);
This code will work even if there are more levels, such as "capitals,Asia,East Asia,China,Beijing".
Note that there is no way to create a variable in JS given a name. Therefore, we provide an initial object, and build the nest structure within it.
Another approach
Another approach is to create a single-level object with keys such as "capitals,Asian,China". That's easier to create, but might be more inconvenient to access. For example, there would be no easy way to find all the Asian capitals. Below, I'm using regexp to pick apart the input into the first part and the final value.
function makeEntry(obj, str) {
const [, key, value] = str.match(/(.*),([^,]+)$/);
obj[key] = value;
}
const data = {};
makeEntry(data, "capitals,Asian,China,Beijing");
console.log(data);
console.log(data["capitals,Asian,China"]);
You can use WeakMap to set the key of the WeakMap object to an object; Array.prototype.shift(), Array.prototype.splice(), Array.prototype.pop() to set the value of the WeakMap object instance.
let Values = "capitals,Asian,China,Beijing";
Values = Values.split(",");
const capitals = {[Values.shift()]:Values.splice(0, 2)};
const wm = new WeakMap;
wm.set(capitals, Values.pop());
console.log(wm.get(capitals));
You can alternatively set the property of an object to the result of JSON.stringify() called on Values.splice(1, 2)
let Values = "capitals,Asian,China,Beijing";
Values = Values.split(",");
const key = JSON.stringify(Values.splice(1, 2));
console.log(key);
const map = {[Values.shift()]:{[key]:Values.pop()}};
console.log(map.capitals[key]);

Categories

Resources