how to transform value string in object to new const js - javascript

i need to convert a object with have key value to new object that contain new const named form platform and have name to value in js how to do it?
posters: [
{ platform: facebook; name: ["user test1","user test2"] },
{ platform: instagram; name: ["Ig test1","Ig test2"] },
]
in to
posters: {
facebook: ["user test1","user test2"] ,
instagram: ["Ig test1","Ig test2"] ,
}

Your input array is invalid. There are no strings around your platform values, and you're separating your object properties with a semi-colon rather than a comma. So you would need to fix that in order to proceed.
It looks as if posters is a property within a larger object so this answer will take that into account.
Use reduce on the posters array to iterate over the objects in the array and return an object where the keys are the platform names, and the values the name arrays.
Since it looks like posters is within a larger object we'll rebuild the object using the spread syntax.
const data={posters:[{platform:"facebook",name:["user test1","user test2"]},{platform:"instagram",name:["Ig test1","Ig test2"]}]};
// Create a new object
const updated = {
// Spread out the old object into it
...data,
// And replace the old `posters` property with an
// object using `reduce`. Destructure the `platform`
// and `name` properties from the object, and then
// use them to add a key and a value to the initial
// object (`acc`/accumulator)
posters: data.posters.reduce((acc, obj) => {
const { platform, name } = obj;
acc[platform] = name;
return acc;
}, {})
};
console.log(updated);
Additional documentation
Destructuring assignment

const postersArray = [
{ platform: facebook, name: ["user test1","user test2"] },
{ platform: instagram, name: ["Ig test1","Ig test2"] }
]
const postersObject = postersArray.reduce((previous, current) => {
return {
…previous,
[current.platform]: current.name
}
},{})

Related

Iterating through a an array executing a switch statement returns TypeError: Cannot assign to read only property 'location' of object '#<Object>'

I have a read only array that i copied to become a mutable array let mutableForecast = [...forecast] I am taking that new array and iterating through it with forEach so i can mutate the array. im trying to use some flow control with a switch statement, but I am getting TypeError: Cannot assign to read only property 'location' of object '#<Object>'
let mutableForecast = [...forecast]
mutableForecast.forEach((obj, i) => {
switch (obj.location) {
case obj.location === "BRITISH_COLUMBIA":
obj.location = "BC"
break;
default:
obj.location = "oother"
}
})
Whats the issue here? I've look at this, this, this and some others but cannot find an answer.
This is what the forecast array looks like before i copied it
It's hard to be sure without knowing where forecast comes from, but I suspect the problem is that the elements of the array are not plain objects, but instances of a custom type that are defined as immutable. Your third link has the likely solution. The key is that you can't convert an array of immutables into an array of mutables simply by using rest & spread in this way. You need to modify the mutability of each item in the array individually.
You probably need something like this:
let mutableForecast = [...forecast]
mutableForecast.forEach((obj, i) => {
// make this element's location property mutable
Object.defineProperty(obj, 'location', { writable: true })
// calculate and set new value
switch (obj.location) {
case 'BRITISH_COLUMBIA':
obj.location = 'BC'
break;
default:
obj.location = 'other'
}
})
This might also work, and I think it's cleaner. You'd have to try it to be sure:
let mutableForecast = Array.from(forecast)
.map(forecastItem => ({
...forecastItem,
location: getShortLocation(forecastItem.location)
}))
function getShortLocation( sourceLocation ) {
switch (sourceLocation) {
case 'BRITISH_COLUMBIA': return 'BC'
default: return 'other'
}
}
The core problem we're working around is that whatever package gives you forecast, it clearly trafficks in some custom datatype, some of whose properties are defined as immutable. That fact doesn't show up when you log the objects, and it isn't changed when you convert an array-like container into an array.
That's because [...forecast] doesn't edit the items, it just copies them as-is from one data structure into another. Actually, be to precise, it copies references to those objects into a new array. If the original objects are weird things with locked properties, then your new array will consist of weird things with locked properties. If we want to change the value of that property on each element, we need to redefine the property before doing so.
Consider a case like this:
let myDog = {
species: 'dog',
name: 'Fido'
}
//> myDog { species: 'dog', name: 'Fido' }
We can create another object with the same properties like so:
let congruentAnimal = {
...myDog
}
//> congruentAnimal { species: 'dog', name: 'Fido' }
If the same property names occurs twice, the engine will only honor the last one:
let myDog = {
species: 'cat',
name: 'Fido',
species: 'dog' // this will cause cat to be ignored
}
//> myDog { name: 'Fido', species: 'dog' }
So, we can override individual object properties while copying by re-declaring those properties last:
let anotherCongruentAnimal = {
...myDog,
species: 'NEW DOG'
}
//> anotherCongruentAnimal { name: 'Fido', species: 'NEW DOG' }
That's what is going on in that second snippet. Here's an expanded version:
// create a real array whose elements are *references* to
// the objects in the array-like forecast
let arrayOfImmutableForecasts = Array.from(forecast)
// create another real array of new objects
// whose property names, values, and metadata are
// the same as the source objects
let arrayOfMutableForecasts = arrayOfImmutableForecasts.map(originalObject => {
let newObject = {
// I think this will also preserve special rules like immutability
...originalObject,
// before we finalize the object, we declare a new simple property
// the engine will _drop_ the implied prop declaration from above
// and define the prop based on this simple declaration instead
location: 'new value'
}
return newObject
})
It seems like you are not allowed to mutate the location property of the objects in the array...
You can try creating a clone of the object and mutate that:
let mutableForecast = [...forecast]
mutableForecast = mutableForecast.map(obj => {
const location = obj.location
const objClone = {}
for (const key in obj) {
if (key !== 'location') objClone[key] = obj[key]
}
switch (location) {
case "BRITISH_COLUMBIA":
objClone.location = "BC"
break;
default:
objClone.location = "other"
}
return objClone
})
If that fails, you can try creating a new property insteade, and later read that property:
let mutableForecast = [...forecast]
mutableForecast.forEach((obj, i) => {
switch (obj.location) {
case "BRITISH_COLUMBIA":
obj.newLocation = "BC"
break;
default:
obj.newLocation = "other"
}
})

From single array convert to an array of object with keys coming from a JSON response -JAVASCRIPT-

I am receiving a json response from an API call. I need to store its keys, and create an array of an object. I am intending to this array of an object is created dynamically no matter the keys of the response.
I've already got the keys like this:
const json_getAllKeys = data => {
const keys = data.reduce((keys, obj) => (
keys.concat(Object.keys(obj).filter(key => (
keys.indexOf(key) === -1))
)
), [])
return keys
}
That returned an array (using a sample json):
['name','username', 'email']
But I am trying to use that array to create an array of object that looks like this one
[
{
name: "name",
username: "username",
email: "Email",
}
];
I've been trying mapping the array, but got multiple objects because of the loop, and I need a single one to make it work.
keys.map(i=>({i:i}))
[
{ i: 'id' },
{ i: 'name' },
{ i: 'username' },
{ i: 'email' }
]
Any hint would be useful!
Thanks in advance :D
What you're looking for is Object.fromEntries, which is ECMA2019, I believe, so available in Node >=14 and will be provided as a polyfill if you employ babel.
I can't quite discern what your reduce should produce, but given the sample input, I would write
const input = ['name','username', 'email'];
const result = Object.fromEntries(input.map(name => ([name, name])));
// result == { name: 'name', username: 'username', email: 'email' }
You're definitely on the right track. One thing to remember is the map function will return the SAME number of output as input. So in your example, an array of 3 returns an array of 3 items.
For this reason, map alone is not going to give you what you want. You may be able to map => reduce it. However, here is a way using forEach instead. This isn't a strictly functional programming style solution, but is pretty straight forward and depending on use case, probably good enough.
let keys = ['name','username', 'email'] //you have this array
const obj = {}; // empty object to hold result
keys.forEach(i => {
obj[i] = i; // set the object as you want
})
console.log(obj); // log out the mutated object
// { name: 'name', username: 'username', email: 'email' }

Merging an array based on key and adding their values. Javascript/Es6/React

There are just 2 objects in an array where I need your attention at. I'm trying to find a way to merge these two objects into a single object based on item.Symbol and then add the values of their corresponding item.TotalCost, item.Price, and item.Quantity to the new object.
I tried doing a Set function but they just merge into 1 object and the values aren't added. I'm receiving an object like this:
[{
CompanyName: "Microsoft Corp."
Date: 1606503905
Price: 215.23
Quantity: 50
Symbol: "MSFT"
TotalCost: 10761.5
},
{
CompanyName: "Microsoft Corp."
Date: 1606503913
Price: 215.23
Quantity: 25
Symbol: "MSFT"
TotalCost: 5380.75
}
]
Here is my code so far:
let set = new Set()
const newSet = Objects.filter(item => {
if (!set.has(item.Symbol)) {
set.add(item.Symbol)
return true;
}
return false},set
)
console.log(newArray)
Note that the Objects variable contains the array of objects shown in the first code block.The set function I wrote only merges them into a single object based on their Symbol but I don't know where to go from here. I'm praying to the Javascript Overlords and Es6 Sith Lords to heed my call. May the force be with you.
Reduce the array of objects to an object, using the Symbol property as the key. If the key doesn't exist on the object, assign a clone of the current item to the key. If it exists, add the current item's values to the existing object:
const arr = [{"CompanyName":"Microsoft Corp.","Date":1606503905,"Price":215.23,"Quantity":50,"Symbol":"MSFT","TotalCost":10761.5},{"CompanyName":"Microsoft Corp.","Date":1606503913,"Price":215.23,"Quantity":25,"Symbol":"MSFT","TotalCost":5380.75}]
const newArray = Object.values(
arr.reduce((acc, o) => {
if(!acc[o.Symbol]) acc[o.Symbol] = { ...o }
else {
acc[o.Symbol].Price += o.Price
acc[o.Symbol].Quantity += o.Quantity
acc[o.Symbol].TotalCost += o.TotalCost
}
return acc
}, {})
);
console.log(newArray)

React object property value being duplicated on .push inside loop

I have a handleCreate function that takes care of taking some user data and inserting it into a database.
Inside the aliasArr.forEach() loop I POST into my DB new user instances for each element in the aliasArr array. This particular code works as expected, if I check the DB, I will find the new members.
After saving the new members, I want to keep the members in the members array so I can pass it along to another function.
For this, I'm doing members.push(memberAttributes); but if I log the contents of members I get the right amount of elements but the alias property value is duplicated (all other properties should have the same value cause they are being added into the same role in a batch operation).
If I have two new users, say: xyz and abc, I get:
[
{alias: "abc", Role: "admin", "grantedBy": "someone"},
{alias: "abc", Role: "admin", "grantedBy": "someone"},
]
Instead of:
[
{alias: "xyz", Role: "admin", "grantedBy": "someone"},
{alias: "abc", Role: "admin", "grantedBy": "someone"},
]
Here's the code:
handleCreate = () => {
const { memberAttributes } = this.state;
const { role, createRoleMember } = this.props;
const roleArr = [];
roleArr.push(role);
const aliasArr = memberAttributes.alias.split(",");
let members = [];
//false hardcoded during debugging.
if (false /* await aliasIsAdmin(memberAttributes.alias, roleArr) */) {
this.setState({ userExists: true });
} else {
memberAttributes["Granted By"] = window.alias;
memberAttributes.Role = role;
memberAttributes.timestamp = Date.now().toString();
this.handleClose();
aliasArr.forEach((currAlias) => {
memberAttributes.alias = currAlias;
console.log("memberAttributes:", memberAttributes);
members.push(memberAttributes);
console.log("members", members);
const marshalledObj = AWS.DynamoDB.Converter.marshall(memberAttributes);
const params = {
TableName: "xxx",
Item: marshalledObj,
};
axios.post(
"https://xxx.execute-api.us-west-2.amazonaws.com/xxx/xxx",
params
);
});
}
createRoleMember(members); //passing members to this function to do more stuff.
};
I'm wondering if this issue is due to memberAttributes being part of the component's state.
The problem here is that you are pushing references to the same object into the array after changing a value within that object. So whenever you make the change to memberAttributes.alias, it's changing the alias to the most recent one. After that, all references to the same object (which in this case is every item in the members array) present the new value in alias.
const obj = { alias: 'abc', role: 'role1' }
const arr = []
arr.push(obj)
obj.alias = 'new alias'
arr.push(obj)
for (var mem of arr) {
console.log(mem)
}
To fix it, you need to create a new object each time and push it onto the array instead, like so:
aliasArr.forEach((currAlias) => {
// Creates a new object in memory with the same values, but overwrites alias
const newMemberAttributes = Object.assign(memberAttributes, { alias: currAlias });
console.log("memberAttributes:", newMemberAttributes);
members.push(newMemberAttributes);
console.log("members", members);
...
}
Similarly, you can use the spread operator to create a deep copy of the object and then reassign alias.
aliasArr.forEach((currAlias) => {
// Creates a new object in memory with the same values, but overwrites alias
const newMemberAttributes = { ...memberAttributes };
newMemberAttributes.alias = currAlias
console.log("memberAttributes:", newMemberAttributes);
members.push(newMemberAttributes);
console.log("members", members);
...
}

How do i make every value of objects in a array as String

I have an array of object something like this
[{id:1, name: "alexander"},{id:2, name: "the great"}]
What is the best way to make the value of all keys as string in the array. So the result should be
[{id:"1", name: "alexander"},{id:"1", name: "the great"}]
Note: My Object is very big and is a combination of number and strings or null and also there is no permanent index of the key in the object. The key in the object can come in any order. Though the key will be at the same place for all the objects. So the desired result should have all the value of all objects in the array as a string.
Use Array.map() to iterate the items. In the map's callback, destructure the objects, extract the id use rest syntax to get the other properties of the object. Convert the id to a string via the String() factory, and then rebuild the object using the spread syntax.
Note: If you expect null or undefined ids, you can use the Nullish coalescing operator (??) to get a default value. For example, String(id ?? '').
const arr = [{id:1, name: "alexander"},{id:2, name: "the great"}]
const result = arr.map(({ id, ...rest }) => ({ id: String(id ?? ''), ...rest }))
console.log(result)
You can use the Array forEach method.
users.forEach(user => user.id = user.id.toString())
where users is the array of objects.
You can try it here:
let users = [{id:1, name: "alexander"},{id:2, name: "the great"}];
users.forEach(user => user.id = user.id.toString());
console.log(users)
You can use map function to iterate each object and save it in each array.
var list = [{ id: "1", name: "alexander" }, { id: "1", name: "the great" }]
var namesValues = list.map((item) => {
return item.name;
});
var idValues = list.map((item) => {
return item.id;
});
console.log(namesValues);
console.log(idValues);

Categories

Resources