Converting an array of objects to Map Immutable.js - javascript

I have an array of objects which I wish to convert into a plain Immutable map of:
name: {
urlname
id
}
Currently I am doing the following data being the array of objects:
data = data.map((data) => ({
name: data.name,
urlName: data.urlName,
id: data.id
}))
What I am trying to transform is the following (data):
[{"id":"10","name":"Dave","urlName":"foo-bar","order":"-100","classId":"12","className":"David","classUrlName":"david-foo-bar"}]
As said above, I would like the name as the key, and both the urlName and the id as values to the key if possible. I would like to loop around data until everything is reduced to that structure if possible.

Since you want to transform the data from shape to shape, you can use the reduce function to do this job.
the reduce function will transform the data into a Map where each key is a name, and the values are the id and urlName
const sample = [{"id":"10","name":"Dave","urlName":"foo-bar","order":"-100","classId":"12","className":"David","classUrlName":"david-foo-bar"}];
const result = sample.reduce((acc, item) => {
return acc.set(item.name, {
id: item.id,
urlName: item.urlName,
})
}, new Immutable.Map())
console.log("Dave's Id", result.getIn(["Dave", "id"]));
console.log("Date's urlName", result.getIn(["Dave", "urlName"]));
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/4.0.0-rc.9/immutable.js"></script>
Check the documentation here for ImmutableJS Reduce and Native Javascript Array.reduce. Both are identical in their API.

Related

React - How to map through an object and display values from nested keys -

I have to map through an object and display all the values from all of the object keys in a list.
The object looks like this.
const books = {
book1: ['comedy', 'action', 'romance'];
book2: ['horror', 'advanture', 'crime'];
book3: ['fantasy, 'humour', 'war'];
}
I tried to create a separate array with all the keys using Object.values like this.
const objValues = Object.values)books
but the result was like this
Array[2]
array[0]
['comedy', 'action', 'romance']
Array[2]
array[1]
['horror', 'adventure', 'crime']
so on...
I have also tried to map through this objValues array and add each value to a new array that I could map over in JSX using forEach but that didn't work.
const allValues = () => {
const res: any = [];
objValues.forEach(key: any) => {
key.forEach((value: any) => {
res.push(value);
});
});
return res;
};
How could I map through all of those values and display them in a list?
Maybe this helps.
this is how I wanted to look
{object.map((value) => {
<div>
<span>{value}</span>
</div>
})}
comedy
action
romance
horror
adventure
crime
You can use flat then map to achieve what you want, don't forget to pass an unique key to the div.
Object.values(books).flat().map(v => <div key={v}> <span>{v}</span> </div>)
Based on your description of the output, you can iterate though the object using a for in loop to index at each "book" array in the "books" object. You would then have the arrays at our disposal to map through.
Something like :
const genres = []
for(let book in books){
books[book].map(title=>{
genres.push(title)
})
}
console.log(genres)
Use Object.values and then use Set to remove duplicates, after that you can iterate using map to render in page.
const books = {
book1: ['crime', 'comedy', 'action', 'romance'],
book2: ['horror', 'advanture', 'crime'],
book3: ['fantasy', 'humour', 'war']
}
const result = [...new Set(Object.values(books).flat())];
console.log(result);
Final code will look something like this
<ul>
{
[...new Set(Object.values(books).flat())].map(item => <li key={item}> {item} </li>)
}
</ul>

Angular get difference function object key

I am trying to compare two or multiple objects using difference() function and then use the object(s) key value to push into an array of just url's, but I can't use dot syntax on an object for some reason any hints?
array this.stores
[
{
name: "Google Play"
url: "https://play.google.com"
}
]
array result
[
{
name: "Google Play"
url: "https://play.google.com"
},
{
name: "Steam Store"
url: "https://store.steampowered.com"
}
]
I'm comparing these 2 arrays of objects like this:
const storesDifference = difference(result, this.stores);
// works as it should stores 'Steam Store'
console.log('difference', storesDifference.url);
// I'm trying to return URL key using dot syntax but without any success
managed to solve this problem using filter function. Works as i wanted.
see below:
const array3 = this.stores
.filter((x) => !result.includes(x))
.concat(result.filter((x) => !this.stores.includes(x)));

How can i get array of object from this data for state and count in reactjs

I am having data file in this array of objects form[{name,state},{name,state},{name,state},{name,state},{name,state}]
I need the state data and number of people belonging to same state, for that i need an array of objects having state and it's count like [{state,count},{state, count},{state,count}]
How can i get this reactjs?
This doesnt have anything to do with ReactJS, which is a library for rendering and managing UI.
In JS you can use a .reduce function to do that. I will produce and array with [{name: string, count: number}]:
const userArray = [{name: Riya, state: US}, {name: Chris, state: DE}]
const stateArray = userArray.reduce((newArray, currentElement) => {
const stateExistsIndex = newArray.findIndex((state) => state.name === currentElement.state)
if (stateExistsIndex !== -1) {
const selectedState = newArray[stateExists]
newArray[stateExists] = { name: selectedState.name, count: selectedState.count++ }
} else {
newArray.push({ name: currentElement.name, count: 1 })
}
return newArray
}, [])
This creates a new array. It loops through the old array and pushes an element to the new array if an state doesnt already exists. If it exists it increases its count by 1. You can of course also do it in a for-of loop which might be more easily understandable.

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' }

Accumulating a Map from an Array In TypeScript

I have an array of TypeScript objects with shape that is essentially the following:
interface MyObject {
id: string
position: number
}
I am trying to convert this array into a map of id to position that looks like this for a JSON POST down the line:
{
"id1": 1,
"id2": 2,
}
One approach is to use an ES6 Map:
array.reduce((map, obj) => map.set(obj.id, obj.position), new Map())
That works, but converting an ES6 Map to JSON is problematic.
I have tried to accumulate the key-value pairs into a pure object literal, but TypeScript has been hating everything I try, which includes Indexable Types, Object.create({}), and a lot of other ideas.
How can I distill a pure object literal of key value pairs from an array of objects?
If your target environment supports ES2019, you could use Object.fromEntries(), like this:
function arrToObjES2019(arr: MyObject[]) {
return Object.fromEntries(arr.map(({ id, position }) => [id, position]));
}
Or, if not, you can make your own polyfill-like version of Object.fromEntries() using array reduce() on an empty object, like this:
function fromEntries<V>(iterable: Iterable<[string, V]>) {
return [...iterable].reduce((obj, [key, val]) => {
obj[key] = val
return obj
}, {} as {[k: string]: V})
}
and then use it:
function arrToObj(arr: MyObject[]) {
return fromEntries(arr.map(({ id, position }) => [id, position]));
}
Either way should let you do what you want:
const arr: MyObject[] = [
{ id: "id1", position: 1 },
{ id: "id2", position: 2 }
];
console.log(JSON.stringify(arrToObj(arr))); // {"id1":1,"id2":2}
Okay, hope that helps. Good luck!
Link to code
I'm not sure why reduce wouldn't be the approach here...
array.reduce((acc, val) =>
Object.assign(acc, {[val.id]: val.position}), {});
Just do this, it is the simplest way:
let newMap = new Map(array.map(obj => [obj.id, obj.position]));

Categories

Resources