how To turn an json object to table of objects - javascript

i used to push a data into array but the data was like bellow can some one tell me how to turn this object to arrray of object
d2 = {
{
id: "BK1",
type: "MAGE",
role: "DARK"
},
{
id: "BK1",
type: "MAGE",
role: "DARK"
},
{
id: "BK1",
type: "MAGE",
role: "DARK"
}
}
to this how i want it to look like:
d2 = [
{
id: "BK1",
type: "MAGE",
role: "DARK"
},
{
id: "BK1",
type: "MAGE",
role: "DARK"
},
{
id: "BK1",
type: "MAGE",
role: "DARK"
}
]

You can use a for ... in loop to iterate over the keys within the object and push those onto an array:
const transformedD2 = [];
for (const key in d2) {
transformedD2.push(d2[key]);
}
You could also use Object.values
The thing is, the object you included as an example isn't valid, as briosheje has pointed out. It only has values, no keys.

Related

Filter objects in array by any value within another array

I have an array of objects, and an array of values that I need to filter the objects by. I can remove duplicates from the array, but trying to figure out how to filter the objects with ids that have a match (or using startsWith()) to filter objects with an id that starts with a given value.
In the end, the object with id "F11v6" should be removed from the resulting array.
let blacklistedComponents = ["F11", "U30"];
let components = [
{ id: "F11v6", type: "unknown" },
{ id: "U30v3", type: "unknown" },
{ id: "CH11", type: "unknown" },
{ id: "CT12", type: "true" },
{ id: "U03v5", type: "unknown" },
{ id: "CT12", type: "true" }
];
console.log(components.filter((v,i,a)=>a.findIndex(v2=>(v2.id===v.id))===i));
You could have a look to the blalisted items an check if id is in the list.
const
blacklistedComponents = ["F11", "U30"],
components = [{ id: "F11v6", type: "unknown" }, { id: "U30v3", type: "unknown" }, { id: "CH11", type: "unknown" }, { id: "CT12", type: "true" }, { id: "U03v5", type: "unknown" }, { id: "CT12", type: "true" }],
result = components
.filter(({ id }) => !blacklistedComponents.some(v => id.includes(v)))
.filter((s => ({ id }) => !s.has(id) && s.add(id))(new Set));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
A single loop approach
const
blacklistedComponents = ["F11", "U30"],
components = [{ id: "F11v6", type: "unknown" }, { id: "U30v3", type: "unknown" }, { id: "CH11", type: "unknown" }, { id: "CT12", type: "true" }, { id: "U03v5", type: "unknown" }, { id: "CT12", type: "true" }],
result = components.filter(
(s => ({ id }) =>
!blacklistedComponents.some(v => id.includes(v)) &&
!s.has(id) &&
s.add(id)
)(new Set)
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can filter those elements that match the ones from the disallowed list using !.some(). Then apply your filter to get rid of the duplicates, e.g.:
const disallowed = ['F11', 'U30'];
const components = [
{id: 'F11v6', type: 'unknown'},
{id: 'U30v3', type: 'unknown'},
{id: 'CH11', type: 'unknown'},
{id: 'CT12', type: 'true'},
{id: 'U03v5', type: 'unknown'},
{id: 'CT12', type: 'true'}
];
const filtered = components
.filter((v) => !disallowed.some(e => v.id.startsWith(e)))
.filter((v,i,a)=>a.findIndex(v2=>(v2.id===v.id))===i);
console.log(filtered)
let blacklistedComponents = ["F11", "U30"]
let components = [
{ id: "F11v6", type: "unknown" },
{ id: "U30v3", type: "unknown" },
{ id: "CH11", type: "unknown" },
{ id: "CT12", type: "true" },
{ id: "U03v5", type: "unknown" },
{ id: "CT12", type: "true" }
]
const idAllowed = id => !blacklistedComponents.some(c=>id.startsWith(c))
const result = [...new Set(components.map(({id})=>id))] // unique ids
.filter(idAllowed) // retain only non-blacklisted ids
.map(id=>components.find(i=>id===i.id)) // correlate to components
console.log(result)
Not entirely sure if you just wanted to remove elements that start with a black listed item, or if ones that contain it anywhere.
Used composition to show how you could do either, and deconstruction to extract the relevant field as the parameter for each filter.
const disallowed = ['F11', 'U30'];
const components = [
{id: 'F11v6', type: 'unknown'},
{id: 'U30v3', type: 'unknown'},
{id: 'CH11', type: 'unknown'},
{id: 'CT12', type: 'true'},
{id: 'U03v5', type: 'unknown'},
{id: 'CT12', type: 'true'}
];
let blackListFilterContains = ( {id} ) => !disallowed.some(testValue => id.includes(testValue));
let blackListFilterStartsWith = ( {id} ) => !disallowed.some(testValue => id.startsWith(testValue));
let uniqueFilter = (value, index, self) => self.indexOf(value) === index;
let result = components.filter(blackListFilterContains);
console.log(result)
result = result.filter(uniqueFilter);
console.log(result)

Remove multiple object from array Javascript [duplicate]

This question already has answers here:
Looping through array and removing items, without breaking for loop
(17 answers)
Closed 2 years ago.
I am trying to delete the all the objects with _id "bennyRawMaterial" from below details array nested in the object:
let recipeBasicRecipes = [{
_id:'12345',
name:'Macaron Shell',
details:[
{
name: 'Sugar',
_id: 'bennyRawMaterial',
type: 'solid',
}
,
{
name: 'Egg white',
_id: '5fef680ca43301322a3224e5',
type: 'solid'
}]
},
{
_id:'14512345',
name:'Macaron Shell',
details:[{
name: 'Castiors gar',
_id: 'bennyRawMaterial',
type: 'solid'
},
{
name: 'oil',
_id: 'bennyRawMaterial',
type: 'solid',
}
, {
name: 'food',
_id: 'bennyRawMaterial',
type: 'solid',
}]
}]
I am using following code to remove the objects, but it skips few of the objects.Please help with the implementation
recipeBasicRecipes.forEach(br => {
br.details.forEach((rm, index) => {
if (rm._id === 'bennyRawMaterial') {
br.details.splice(index, 1);
} else {
return true;
}
});
maintain a global ids array,
and go through the details array of each object
check the id exist in global ids array
let recipeBasicRecipes = [{
_id: '12345',
name: 'Macaron Shell',
details: [{
name: 'Sugar',
_id: 'bennyRawMaterial',
type: 'solid',
},
{
name: 'Egg white',
_id: '5fef680ca43301322a3224e5',
type: 'solid'
}
]
},
{
_id: '14512345',
name: 'Macaron Shell',
details: [{
name: 'Castiors gar',
_id: 'bennyRawMaterial',
type: 'solid'
},
{
name: 'oil',
_id: 'bennyRawMaterial',
type: 'solid',
}, {
name: 'food',
_id: 'bennyRawMaterial',
type: 'solid',
}
]
}
]
var uniqueIds = []; //global ids array
recipeBasicRecipes.forEach(el => {
let details = [];//unique details array
el.details.forEach((dt, i) => {
let id = dt._id;
if (!uniqueIds.includes(id)){ //check id exists in global ids array
uniqueIds.push(id);
details.push(dt); //copy unique details
}
});
el.details = details; //update details with unique details
});
console.log(recipeBasicRecipes)

Recursive counting in arbitrary nested object

I'm attempting to do some data visualization and dealing with this dataset. Object with arbitrary nested objects. I'm trying to count how many times different values appear in a key. This is just a snippet of the dataset, in the original the owns nested objects go 7+ levels deep.
Example dataset I'm working with:
var companyData = [{
company: 'Pepsico',
type: 'parent',
owns: [
{
company: 'Cheetos',
type: 'chips',
owns: [{
company: 'CheezyChipCo',
type: 'chips',
owns: []
}]
},
{
company: 'Gatorade',
type: 'drink',
owns: [{
company: 'Powerade',
type: 'drink',
owns: []
}]
},
],
}];
I'm thinking I'll have to do a Recursion or a Flatten type operation. So I can put all the type values into an array like this.
What I'm trying to achieve:
[ 'drink', 'drink', 'chips', 'chips', 'parent' ]
I need to open up owns so I can properly count the type values. I feel like there are two ways I can go about it. Either recursion to go deep into an object. OR flatten the objects, so that all the nests are on the same level. I'll probably use Object[keys] in combination with .filter, .some, or .reduce. But I am so stumped on how and in what order, and would love some help! Here's my psuedo:
if (type of object's key is an Object)
&& if (object's key === "type")
then push that type.value to an array
else if (type of object's key !=== object)
then just return the new sorted array
Sorry, real frontend dev hours. I don't know if that made sense and if posting all my failed code attempts would help.
Using straightforward recursion...
var companyData = [{ company: 'Pepsico', type: 'parent', owns: [{ company: 'Cheetos', type: 'chips', owns: [{ company: 'CheezyChipCo', type: 'chips', owns: [] }] }, { company: 'Gatorade', type: 'drink', owns: [{ company: 'Powerade', type: 'drink', owns: [] }] },], }];
function mapTypes(arr, acc = []) {
for (const o of arr) {
acc.push(o.type);
if (o.owns.length > 0) {
acc = mapTypes(o.owns, acc)
}
}
return acc;
}
console.log(mapTypes(companyData));
You can write a simple recursive flatten -
const flatten = ({ type, owns = [] }) =>
[ type, ...owns.flatMap(flatten) ]
const input =
[{company:'Pepsico',type:'parent',owns:[{company:'Cheetos',type:'chips',owns:[{company:'CheezyChipCo',type:'chips',owns:[]}]},{company:'Gatorade',type:'drink',owns:[{company:'Powerade',type:'drink',owns:[]}]}]}]
console.log(input.flatMap(flatten))
[
"parent",
"chips",
"chips",
"drink",
"drink"
]
Here is my solution. You can do it with a reduce function.
var companyData = [{
company: 'Pepsico',
type: 'parent',
owns: [
{
company: 'Cheetos',
type: 'chips',
owns: [{
company: 'CheezyChipCo',
type: 'chips',
owns: []
}]
},
{
company: 'Gatorade',
type: 'drink',
owns: [{
company: 'Powerade',
type: 'drink',
owns: []
}]
},
],
}];
let arr = []
const formattedData = (data) => data.reduce((acc, curr) => {
arr.push(curr.type);
if (Array.isArray(curr.owns)) {
formattedData(curr.owns)
}
return arr;
}, []);
console.log(formattedData(companyData))

Construct an array of objects after doing a filter for an array in JavaScript

I was able to filter the array but when I'm trying to create an array of objects out of the filtered data, the result appears to be undefined. How do I construct an array of objects in the below format. Could anyone please help?
[{ brand: 'BMW'}, { brand: 'Audi'}]
Snippet
const cars = [{
name: 'BMW',
type: 'Sedan'
}, {
name: 'Audi',
type: 'SUV'
}, {
name: 'BMW',
type: 'SUV'
}]
const result = cars.filter(({
type
}) => type === 'SUV').map((car) => {
brand: car.name
})
console.log(result)
If you want to return an object literal from the arrow function, you need to enclose that object literal in parentheses to distinguish it from a code block, which also happens to be enclosed in curly braces:
result = cars.map(car => ({
brand: car.name
}));
It's funny that your code doesn't cause an error. It's just because there's a label syntax in JavaScript, so your code inside the arrow function basically creates a brand label to a loose value of car.name.
Basically you need to wrap the object in parentheses to distinguish it from a block statement.
const
cars = [{ name: 'BMW', type: 'Sedan' }, { name: 'Audi', type: 'SUV' }, { name: 'BMW', type: 'SUV' }],
result = cars
.filter(({ type }) => type === 'SUV')
.map(({ name: brand }) => ({ brand }));
// ^^^^^^^^^^^ wrap it
console.log(result);
You are missing a pair of parenthesis around the new implicitly returned object from the map function. This is a tricky syntax of es6.
const cars = [{
name: 'BMW',
type: 'Sedan'
}, {
name: 'Audi',
type: 'SUV'
}, {
name: 'BMW',
type: 'SUV'
}]
const result = cars.filter(({
type
}) => type === 'SUV').map((car) => ({
brand: car.name
}))
console.log(result)
For doing this you can declare a variable and return it.
const cars = [{
name: 'BMW',
type: 'Sedan'
}, {
name: 'Audi',
type: 'SUV'
}, {
name: 'BMW',
type: 'SUV'
}]
const result = cars.filter(({
type
}) => type === 'SUV').map((car) => {
let obj = {brand: car.name}
return obj
})
console.log(result)

Filter JavaScript array based on object property from another array

I have 2 arrays in JavaScript. One of which needs filtering based on a property from the other one.
I have a movies list such as this:
[
{
id: 1,
type: 'movies',
attributes: {
name: 'Batman'
}
},
{
id: 2,
type: 'movies',
attributes: {
name: 'Spiderman'
}
},
...
]
I then have another array which contains movies that a user has watched but they are within a nested object within the array as a relationship following the JSON API spec.
[
{
id: '1',
type: 'moviesWatched',
attributes: {
comment: 'Excellent film, would recommend to anyone who loves a action film!'
},
relationships: {
movie: {
data: {
type: 'movies',
id: 2
}
}
}
}
]
What I need to achieve is I need to cross reference the id from watchList[].relationships.movie.data.id with the first array. Obviously, this list is a lot longer in production but what I am hoping to achieve is to have a full list of movies which the use has watched with the name of the movie based off 2 arrays formatted like this to save me having to store needless data inside of the database.
The outcome of the array would be something along the lines of...
[
{
id: 1,
type: 'movies',
attributes: {
name: 'Batman'
},
meta: {
watched: false
}
},
{
id: 2,
type: 'movies',
attributes: {
name: 'Spiderman'
},
meta: {
watched: true
}
}
]
Here is what I have currently, which is working but I don't know if there is a better way to go about it...
movies.map((movie) => {
const watched = watchedMovies.find((searchable) => {
return searchable.relationships.movie.data.id === searchable.id;
});
movie.meta.watched = watched || false;
return movie;
});
Since you said the list can be long, you can extract the "watched" movie ids to a Set and then set the meta.watched property of a movie based on whether or not its id is in the set:
const movies = [{
id: 1,
type: 'movies',
attributes: {
name: 'Batman'
}
},
{
id: 2,
type: 'movies',
attributes: {
name: 'Spiderman'
}
}
];
const watched = [{
id: '1',
type: 'moviesWatched',
attributes: {
comment: 'Excellent film, would recommend to anyone who loves a action film!'
},
relationships: {
movie: {
data: {
type: 'movies',
id: 2
}
}
}
}];
const watchedSet = new Set(watched.map(m => m.relationships.movie.data.id));
movies.forEach(movie => movie.meta = {watched: watchedSet.has(movie.id)});
console.log(movies);

Categories

Resources