How to Iterate through an array object inside another array object (JSON)? - javascript

The following is a list of users I receive from an API call that gets the list of users from AWS cognito. I want to be able to iterate through it to display the name and email of the user on a web page. I am trying result[0].attributes[3] to iterate to "given_name", result being the object.

You can use filter to determine if an object property can be found, and then return that object.
result[0].Attributes.filter(obj => obj.name === name);
Here's an example:
let result = [{
Attributes: [{
name: "Mario"
},
{
name: "Luigi"
},
{
name: "Toad"
},
{
name: "Peach"
}
]
}]
function lookfor(name) {
return result[0].Attributes.filter(obj => obj.name === name);
}
console.log(lookfor("Mario"));
console.log(lookfor("Peach"));

for(var i in array){
var attr = array[i].Attributes;
for(var l in attr){
// attr[l].Name returns name
// attr[l].Value returns values
}
}

You can iterate an array using map
arrributes.map(function(arr) => {
console.log(arr.Name, arr.Value)
})

const response = [
{ Attributes: [
{Name: 'given_name', Value: 'name 1'},
{Name: 'family_name', Value: 'family 1'},
{Name: 'email', Value: 'email1#gmail.com'}
]
},
{ Attributes: [
{Name: 'given_name', Value: 'name 2'},
{Name: 'family_name', Value: 'family 2'},
{Name: 'email', Value: 'email2#gmail.com'}
]
},
];
const users = response.map((ele) => {
const { Attributes } = ele;
return Attributes.reduce((agg, {Name, Value}) => {
if (Name === 'given_name') {
agg.name = Value;
}
if (Name === 'email') {
agg.email = Value;
}
return agg;
}, {});
});
console.log(users);

Object.keys(result).forEach(key => {
let resultObject = result[key].map(array => {
if (array.Name == "given_name") {
console.log(array.value)
} else if (array.Name == "email") {
console.log(array.value);
}
});
});

Related

Check if object key exists in array of object and add if not exists

Do you know guys how to do it simplier/smarter ?
I wanna add a label key with name value if the key doesn't exist in object. This is my list:
myList = [
{
name: 'Candy',
label: 'xx',
},
{
name: 'Mike',
label: 'yy',
},
{
name: 'Betty',
}
]
And my solution:
assignLabel = list => {
const casesWithoutLabel = list.filter(({ label }) => !label).map(item => ({
...item,
label: item.name
}))
const casesWithLabel = list.filter(({ label }) => label)
return [ ...casesWithoutLabel, ...casesWithLabel ]
}
assignLabel(myList)
Output
[
{
name: 'Candy',
label: 'xx',
},
{
name: 'Mike',
label: 'yy',
},
{
name: 'Betty',
label: 'Betty'
}
]
It gives me good output, but it's not elegant and I don't have idea how to improve now. Please help me!
I have create simple script for you, please have a look!
let myList = [
{
name: 'Candy',
label: 'xx',
},
{
name: 'Mike',
label: 'yy',
},
{
name: 'Betty',
}
];
let list = myList.map((item) => {
let {name, label} = item;
if(label == undefined){
item["label"] = name;
}
return item;
});
console.log(list);
Your code seems very advanced for only assigning a property, so maybe I am missing something, but you could simply loop through the list (or filter oc)
myList = [{name: 'Candy',label: 'xx',},{name: 'Mike',label: 'yy',},{name: 'Betty',}];
for(const obj of myList)
if(!obj.label)obj.label = obj.name;
console.log(myList);

How to update a value in nested array based on the given index and return original array in javascript?

I have an index '3_1_0' and the following array:-
var fields = [
{
name: 'a'
},
{
name: 'b'
},
{
name: 'c'
},
{
name: 'd',
fields: [
{
name: 'd1'
},
{
name: 'd2',
fields: [
{
name: 'd2.1'
}
]
}
]
}
]
I need to extract the element from the above fields array based on the index. so 3_1_0 will extract following
{
name: 'd2.1'
}
Update the value from d2.1 to some other value like 'new_d2.1' and attach the updated value at the same index in original fields array and return the updated fields array. How this can be done?
You can use Array.reduce to get the desired result. We start by splitting the index into an array, then reducing to get the result.
We'll use some Optional Chaining to ensure we'll return undefined if no value is found (say our index was '7_10_20').
Once we've found our object, we can set the required property.
const fields = [ { name: 'a' }, { name: 'b' }, { name: 'c' }, { name: 'd', fields: [ { name: 'd1' }, { name: 'd2', fields: [ { name: 'd2.1' } ] } ] } ];
const index = '3_1_0'
function setValue(fields, index, property, value) {
const obj = index.split('_').reduce((acc, key) => {
return acc?.[key] || acc?.fields?.[key];
}, fields);
// Only update if we actually find anything
if (obj) {
obj[property] = value
}
}
setValue(fields, '3_1_0', 'name', 'new_d2.1');
console.log("Fields:", fields);
const data = [{ name: 'a' }, { name: 'b' }, { name: 'c' }, { name: 'd', fields: [ { name: 'd1' }, { name: 'd2', fields: [ { name: 'd2.1' } ] } ] } ];
let givenIdxs = "3_1_0";
let indexes = givenIdxs.split("_");
let result = data[indexes[0]];
for(let idx = 1; idx < indexes.length; idx++){
result = result.fields[indexes[idx]];
}
console.log(result);

Javascript - Remove object from nested array

I have array of objects, each object must have key and title, but children is optional, and it can be nested, i can have children inside of children many times. I want to remove some object by provided key value (for example key 677). I tried with filter but i only remove first level. Also have tried recursion, but not sure if i did it right.
const data = [{
key: '1',
title: 'title 1',
children: [{
key: '098',
title: 'hey',
children: [{
key: '677',
title: 'child'
}]
}]
},
{
key: '123',
title: 'tile 111'
},
{
key: '345',
title: 'something'
}
];
const rem = '677';
const del = (el) => {
if (!el.children) {
return el.key !== rem;
} else {
if (el.key !== rem) {
del(el.children);
return el;
}
}
};
const res = data.filter((el) => {
return del(el);
});
console.log(res);
I guess your existing solution is like
const data = [
{
key: '1',
title: 'title 1',
children: [{
key: '098',
title: 'hey',
children: [{ key: '677', title: 'child'}]
}]
},
{ key: '123', title: 'tile 111' },
{ key: '345', title: 'something' }
];
function removeByKey(arr, removingKey){
return arr.filter( a => a.key !== removingKey);
}
So it works on the first level but not deeply.
Just change it like that will do the jobs
function removeByKey(arr, removingKey){
return arr.filter( a => a.key !== removingKey).map( e => {
return { ...e, children: removeByKey(e.children || [], removingKey)}
});
}
Little warning, children property will not be set to [] for every item not having any children.
So how it works? Well instead of keeping acceptable items as they are, we make a copy using {...e} that's equivalent to {key:e.key, title:e.title, children:e.children} in this case.
We know force to override the property children with removeByKey(e.children || [], removingKey), so we call the method recursively. Not the function works deeeply.
I would use a recursion approach with findIndex and splice. Using some will allow the code to exit without running through the entire tree.
const data = [{
key: '1',
title: 'title 1',
children: [{
key: '098',
title: 'hey',
children: [{
key: '677',
title: 'child'
}]
}]
},
{
key: '123',
title: 'tile 111'
},
{
key: '345',
title: 'something'
}
];
const removeKey = (data, key) => {
// look to see if object exists
const index = data.findIndex(x => x.key === key);
if (index > -1) {
data.splice(index, 1); // remove the object
return true
} else {
// loop over the indexes of the array until we find one with the key
return data.some(x => {
if (x.children) {
return removeKey(x.children, key);
} else {
return false;
}
})
}
}
console.log(removeKey(data, '677'))
console.log(JSON.stringify(data));
You can use some simple recursion to do the trick:
const data = [
{
key: '1',
title: 'title 1',
children: [
{
key: '098',
title: 'hey',
children: [{ key: '677', title: 'child'}]
}
]
},
{ key: '123', title: 'tile 111' },
{ key: '345', title: 'something' }
];
function removeByKey(key, arr) {
// loop through all items of array
for(let i = 0; i < arr.length; i++) {
// if array item has said key, then remove it
if(arr[i].key === key) {
arr.splice(i, 1);
} else if(typeof(arr[i].children) !== "undefined") {
// if object doesn't have desired key but has children, call this function
// on the children array
removeByKey(key, arr[i].children);
}
}
}
removeByKey('098', data);
console.log(data);
This may be a little easier to understand than the other answer provided.

Updating selection of array's values

I have two arrays. Each array could have a different number of objects but they each have the same properties but could have different values. For example
var Array1 = [ { id: '1', value: a },
{ id: '2', value: b } ]
var Array2 = [ { id: '', value: c },
{ id: '', value: d },
{ id: '', value: a } ]
What I want
AfterArray = [ { id: '1', value: a },
{ id: '3', value: c },
{ id: '4', value: d } ]
What's happening is that array1's object will be removed if it doesn't have array2's value. If it does have array2's value, it will keep the original id. If an object is in array2 that isn't in array1, an id will be generated (UUID).
I'm assuming it might go something like this
afterArray = []
this.Array1.forEach((res, i) => {
this.Array2.forEach((res2, 2) => {
if(res.value == res2.value){
afterArray = afterArray.concat(this.Array1[i])
}
else {
// do something if values are not present then add to array.
// if added, add id to those empty properties.
}
})
})
Thanks!
You just need a simple mapping over Array2 with a find inside it, to find the matching value in Array1 if it exists:
const array1 = [
{
id: '1',
value: 'a'
},
{
id: '2',
value: 'b'
}
];
const array2 = [
{
id: '',
value: 'c'
},
{
id: '',
value: 'd'
},
{
id: '',
value: 'a'
}
];
const generateId = (() => {
// example generator function, use your own instead
let possibleIds = ['3', '4'];
let i = -1;
return () => {
i++;
return possibleIds[i];
};
})();
const result = array2.map(({ id, value }) => {
// find a matching value in array1 to merge the id:
const foundArr1Item = array1.find(({ value: ar1Val }) => ar1Val === value);
// otherwise, generate a new ID:
if (foundArr1Item) return { value, id: foundArr1Item.id };
return { value, id: generateId() };
});
console.log(result);
If I understood it right, this should do your job:
(find the comments in the code)
Array1 = [
{
id: '1',
value: "a"
},
{
id: '2',
value: "b"
}
]
Array2 = [
{
id: '',
value: "c"
},
{
id: '',
value: "d"
},
{
id: '',
value: "a"
}
]
// keep Array1's objects if it has a value matching a value from any Array2 object
// Also remove those objects from Array2
newArray1 = Array1.reduce((acc, elem) => {
let indexOfObInArray2 = Array2.findIndex(eachArray2Elem => {
return elem.value == eachArray2Elem.value
});
if (indexOfObInArray2 > -1) {
acc.push(elem);
Array2.splice(indexOfObInArray2, 1);
}
return acc;
}, [])
// Array of ids already taken by Objects from Array2, if they are non empty
idsTakenInArray2 = Array2.reduce((acc, x) => {
if (x.id != "") {
acc.push(x.id);
}
return acc;
}, []);
// random number to give ids
randomId = 1;
Array2 = Array2.map(eachElem => {
if (eachElem.id == '') {
while (Array1.find(eachArray1Elem => {
return eachArray1Elem.id == randomId
}) || idsTakenInArray2.indexOf(randomId) !== -1) {
randomId++;
}
eachElem.id = randomId;
idsTakenInArray2.push(randomId);;
}
return eachElem;
})
console.log(newArray1.concat(Array2));
check this, here is the code online https://stackblitz.com/edit/angular-zhzuqk , check your console you will see what you want to have as result
formtarrays(array1,array2) {
let ar = array1.concat(array2);
// delete items that exist in array1 but not in array2
ar = ar.filter((elem) => {
return !(array1.findIndex(item => item.value === elem.value) !== -1 && array2.findIndex(item => item.value === elem.value) === -1)
})
// get distinct values
const idList = [];
const distinct = [];
ar.forEach((item, index) => {
if (item !== undefined) {
idList['id'] = item.value;
if (idList.indexOf(item.value) < 0) {
if(item.id === '') {
item.id = (index + array1.length).toString();
}
distinct.push(item);
idList.push(item.value);
}
}
})
console.log(distinct);
return distinct;
}

Convert object with one property into parent property

I have converted javascript object from xml, this is example of object:
{
name: 'current name',
attr1: 'attribute1',
attr2: 'attribute2',
address: {
name: 'name1',
value: {
value: '12'
},
attr3: {
name: 'no name',
attr4: {
attr4: 'attribute4'
}
}
},
price: {
price: '500'
},
in_house: {
in_house: '2'
}
}
how I can convert into this:
{
name: 'current name',
attr1: 'attr1',
address:{
name: 'name1',
value: '12',
attr3: {
name: 'no name',
attr4: 'attribute3'
}
}
attr2: 'attr2',
price: 500,
in_house: 2
}
need convert all unusefull object into property, example
{
price :
price: '500'
}
into
{ price: '500'}
You could use an iterative, recursive approach for the keys and their values.
function moveUp(object, last) {
var keys = Object.keys(object);
if (keys.length === 1 && keys[0] in last) {
last[keys[0]] = object[keys[0]];
if (last[keys[0]] !== null && typeof last[keys[0]] === 'object') {
moveUp(last[keys[0]], last);
}
return;
}
keys.forEach(function (k) {
if (object[k] !== null && typeof object[k] === 'object') {
moveUp(object[k], object)
}
});
}
var object = { name: 'current name', attr1: 'attribute1', attr2: 'attribute2', address: { name: 'name1', value: { value: '12' }, attr3: { name: 'no name', attr4: { attr4: 'attribute4' } } }, price: { price: '500' }, in_house: { in_house: '2' }, test: { test: { test: { banane: 42 } } } };
moveUp(object);
console.log(object);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Here is a recursive function that will iterate over the root object and pass over every node in it to see if the current node has an immediate child of the same name.
const obj = { name: 'current name', attr1: 'attribute1', attr2: 'attribute2',
address: { name: 'name1', value: { value: '12' }, attr3: { name: 'no name', attr4: { attr4: 'attribute4' }}}, price: { price: '500' }, in_house: { in_house: '2' }}
// helper function to check if a value is an object
const isObject = thing => (
typeof thing !== 'undefined' &&
typeof thing.constructor &&
thing.constructor === Object
)
const mutateUselessProperties = (root) => {
// we need to recursively go through the root object and return it's result
// after removing properties so we create an inner function for recursion
const go = (obj) => {
// if it's just a value return it
if (!isObject(obj)){
return obj
}
// it's an object so we loop over the keys
for (let key in obj) {
// check if it's an object with a child of the same key
if (isObject(obj[key]) && obj[key][key]) {
// reassign the property to it's child of the same name
obj[key] = obj[key][key]
}
// check if it's still an object after possible reassignment
if (isObject(obj[key])) {
// it's an object so recrusively go through the child properties
obj[key] = go(obj[key])
}
// may as well check if we are dealing with an array at the same time
if (Array.isArray(obj[key])) {
obj[key] = obj[key].map(go)
}
}
// return the current iteration
return obj
}
// run the recursive iteration
go(root)
// return the root object that has been mutated
return root
}
console.log(mutateUselessProperties(obj))
If the nested single properties all have the same name with the parent property then the following should work;
var obj = {
name: 'current name',
attr1: 'attribute1',
attr2: 'attribute2',
address: {
name: 'name1',
value: {
value: '12'
},
attr3: {
name: 'no name',
attr4: {
attr4: 'attribute4'
}
}
},
price: {
price: '500'
},
in_house: {
in_house: '2'
}
};
for (var prop in obj) typeof obj[prop] === "object" && Object.keys(obj[prop]).length === 1 && (obj[prop] = obj[prop][prop]);
console.log(obj);

Categories

Resources