Collect unique values of array in an array React - reactjs

Can someone let me know how I can create a list of unique languages from an array inside another array.
This is the dataset...
const people = [
{
//Other values, name date etc.
languages: ["English", "Spanish"]
},{
//Other values, name date etc.
languages: ["English", "Mandarlin"]
},{
//Other values, name date etc.
languages: ["Japanese"]
},....
and here is as far as I've got....
const languagesOptions = this.props.data.map((item, index) => {
new Map(
...item.languages.map(d => [d.languages])
)
});
I can use the new Map function when it's not an array but can't get it to work with the languages data.
Thanks

You could map over it and use Set to remove dupes.
const people = [{
languages: ["English", "Spanish"]
}, {
languages: ["English", "Mandarlin"]
}, {
languages: ["Japanese"]
}];
const languages = [...new Set(people.flatMap(({ languages }) => languages))];
console.log(languages);

Related

Flatten object type with array property in typescript react for output to react-data-grid

Apologies in advance if this has already been answered, but I am struggling to find an answer to it...
I have an array which contains a 2 d array property.
What I want returned is a type which contains has the inner array as a flat object.
So for example my array could be
{
name: "Widget",
event: "Xmas",
pilot: "Dave",
session: "drinking",
frameType: "flight",
stint: 2016,
plane: "737",
**data: {
"114": "137.623",
"115": "51.090",
}**
}
What I would like is my output to be
{
name: "Widget",
event: "Xmas",
pilot: "Dave",
session: "drinking",
frameType: "flight",
stint: 2016,
plane: "737",
"114": "137.623",
"115": "51.090",
,
}
Now here is my code to generate the array.
The Type:
type TableItem =
{
name: string,
event: string,
session: string,
frameType: string,
stint: number,
chassis: string,
driver: string,
data: (string | number)[][]
};
const getTableItem = (index: number) =>
{
const d = data[index];
//Transformentry just makes the id 3 digits
const dataItems = Object.assign({}, ...Object.entries(d.data).map(transformEntry));
const tableItem: TableItem = {
name: d.name,
event: d.event,
piolt: d.pilot,
session: d.session,
frameType: d.frameType,
stint: d.stint,
plane: d.plane,
data: dataItems
};
return tableItem;
};
const rows = (data.map((d, index) => { return getTableItem(index); }));
Now what I want is the rows variable(const) to contain the flattened array. I have tried flat/flatmap and reduce but can't get them to work.
If anyone can point me in the right direction with this it would be massively appreciated. Basically the rows const will then be passed to the react-data-grid component.
Thanks in advance
Steve
The data property is not an array, it is another object which may be why things like flatMap did not work for you.
If you're happy to retain the data property but also flatten the properties therein into the top level object you could just flatten it with the spread operator ...:
const input = {
name: "Widget",
event: "Xmas",
pilot: "Dave",
session: "drinking",
frameType: "flight",
stint: 2016,
plane: "737",
data: {
"114": "137.623",
"115": "51.090",
}
};
const result = {...input,...input.data};
console.log(result);
If you must get rid of the data property you could just add delete result.data; to the above.

How to convert an array of dictionaries into an array of keys using react

Given a list:
let names = [{name: "bobby"}, {name: "sydney"}, {name: "Paul"}, {name: "Grace"}
I want the output to be ["bobby", "sydney", "Paul", "Grace"]
Here is what I have tried:
var items = Object.keys(names).map(function(i) {
return names[i];
})
const items = Object.keys(names).map((key)=>names[key]);
this.setState({items});
console.log(this.state.items);
names.map(({ name }) => name)
const names = [{
name: "bobby"
}, {
name: "sydney"
}, {
name: "Paul"
}, {
name: "Grace"
}];
const keys = names.map(({
name
}) => name);
console.log(keys);
A note about react keys, they should be unique within the rendered siblings, i.e. they should be unique within the dataset. Names alone may not provide sufficient uniqueness.
A second note, you might not want to generate your react keys separately from where you need them, i.e. generally they are created when you are mapping JSX.
This is not really related to React. You can do that with JavaScript, for instance using API like map().
Here is an example:
let arr = names.map(obj => obj.name);

How can I use .map on an array to create a new JSON object for each item?

how can I use map on an array to map each item to a new JSON structure?
For example my original array looks like this:
result= [
{
"pageIndex":1,
"pageName":"home",
"cssConfiguration":"fa fa-home"
}, ...]
And I want to use .map to create a different structure for the JSON objects, for example:
modifiedResult = [
{
"id":1,
"name":"Home"
},...]
I've tried to do something like this:
result.map((resultItem) => { name: resultItem["pageName"], id:resultItem["pageIndex"]});
But it doesn't work :(
In your approach are missing the parentheses within the handler:
result.map((resultItem) => { name: resultItem["pageName"], id:resultItem["pageIndex"]});
^
You can use the function map and destructuring-assignment as follow:
let arr = [ { "pageIndex":1, "pageName":"home", "cssConfiguration":"fa fa-home" }],
result = arr.map(({pageIndex: id, pageName: name}) => ({id, name}));
console.log(result)
You can use map:
const result = arr.map(({pageIndex, pageName}) => ({id: pageIndex, name: pageName}))
An example:
let arr = [
{
"pageIndex":1,
"pageName":"home",
"cssConfiguration":"fa fa-home"
}]
const result = arr.map(({pageIndex, pageName}) => ({id: pageIndex, name: pageName}))
console.log(result)

Normalizr - How to handle nested entities that are already normalized

I have entities in very nested JSON that already follow the normalizr format where the idAttribute is already the key where the object is defined:
groups: [{
id: 'foo',
families: {
smiths: {
people: [{
id: 'sam',
}, {
id: 'jake',
}],
},
jones: {
people: [{
id: 'john',
}, {
id: 'sue',
}],
},
},
}];
In this example, notice that the families attribute is using the id (smiths, jones) to identify the people who are an array of objects with ids.
The schemas for this might look like:
const person = new Entity('person');
const family = new Entity('family', {
people: [person],
}, {idAttribute: ???});
const group = new Entity('family', {
family: [family],
});
QUESTION: Is there a way to specify that a schema's idAttribute is the key where it is defined? In other words, how would I define the schema for Family as it's related to groups and people?
Another question, is there a way to denormalize a flattened state so that the families families: {[id]: obj} pattern stays the same as it is in the example json above?
Is there a way to specify that a schema's idAttribute is the key where it is defined?
Yes. The idAttribute function takes 3 arguments: value, parent, and key. Please read the docs. In your case, you can use the key, along with schema.Values
const family = new schema.Entity('families', {
people: [ person ]
}, (value, parent, key) => key);
const families = new schema.Values(family);
const group = new schema.Entity('groups', {
families
});
For denormalize, you'll need a separate schema for family, since the ID can't be derived from the key.

Mapping an array into an object, key is not defined

const lessons = [
[ 'Chemistry', '9AM', 'Mr. Darnick' ],
[ 'Physics', '10:15AM', 'Mrs. Lithun'],
[ 'Math', '11:30AM', 'Mrs. Vitalis' ]
];
let lessonsAsObject = {};
lessons.map(lesson => {
lessonsAsObject[lesson[subject]] = lesson[0];
});
I want to translate this array into an object, matching the data with the keys, subject, time and teacher.
However the code above returns
reference error, "subject is not defined".
You can use array destructuring to get the params from the array, and then create an object for each of them, using the shorthand and computed property names.
If you want the end result to be an object, instead of array of objects, you can combine them to one object using spread syntax, and Object#assign:
You can use the subject as key:
const lessons = [["Chemistry","9AM","Mr. Darnick"],["Physics","10:15AM","Mrs. Lithun"],["Math","11:30AM","Mrs. Vitalis"]];
const lessonsAsObject = Object.assign(...lessons.map(([subject, time, teacher])=> ({
[subject]: {
time,
teacher
}
})));
console.log(lessonsAsObject);
Or the index as key:
const lessons = [["Chemistry","9AM","Mr. Darnick"],["Physics","10:15AM","Mrs. Lithun"],["Math","11:30AM","Mrs. Vitalis"]];
const lessonsAsObject = Object.assign(...lessons.map(([subject, time, teacher], index)=> ({
[index]: {
subject,
time,
teacher
}
})));
console.log(lessonsAsObject);
If you just want an array of objects:
const lessons = [["Chemistry","9AM","Mr. Darnick"],["Physics","10:15AM","Mrs. Lithun"],["Math","11:30AM","Mrs. Vitalis"]];
const lessonsAsObject = lessons.map(([subject, time, teacher])=> ({ subject, time, teacher }));
console.log(lessonsAsObject);
If what you're trying to end up with is an array of objects where the objects have named properties instead of your array positions, then you could do this:
var lessonsList = lessons.map(function(lesson) {
return {subject: lesson[0], time: lesson[1], teacher: lesson[2]};
});
This would give you an array of objects like this:
[{subject: "Chemistry", time: "9AM", teacher: "Mr. Darnick"},
{subject: "Physics", time: "10:15AM", teacher: "Mrs. Lithun"},
{subject: "Math", time: "11:30AM", teacher: "Mrs. Vitalis"}]
If you're looking for some different type of output, then please show an example of exactly what output you're trying to achieve.
However the code above returns the reference error, "subject is not
defined".
That is because the identifier subject is not defined anywhere. If you intended to use it as a static property name, then you can do lesson["subject"]. If you intended to have subject be a variable with some property name in it, then you have to define and assign that variable.

Resources