fetching nested object value - javascript

I have this code where it will log the value into the console
const table = { index: 0,
data: {items:[
{students: {name: Gloria, age: 24, gender: female} , id: 025},
{students: {name: Alex, age: 27, gender: male} , id: 024}],
total: 2}
}
const result = table.data.items.map(Object.values);
console.log(result);
and the console will appear as
[[{name: Gloria, age: 24, gender: female} , 025],
[{name: Alex, age: 27, gender: male} , id: 024]]
The only problem is I want only the values to appear such as
[[{Gloria, 24, female}, 025],
[{Alex, 27, male}, 024]
can somebody tell me what is wrong in here?

for this below
[[{Gloria, 24, female}, 025],
[{Alex, 27, male}, 024]
this object is not valid since Objects should have key-value pairs,
{Gloria, 24, female}
This below is valid
[[{name: Gloria, age: 24, gender: female} , 025],
[{name: Alex, age: 27, gender: male} , id: 024]]
or you can make it like this :
[[[Gloria, 24, female], 025],
[[Alex, 27, male], 024]
Do lemme know if this works, ill let you know how to do that
EDIT: ANSWER :
const table = { index: 0,
data: {items:[
{students: {name: "Gloria", age: 24, gender: "female"} , id: 25},
{students: {name: "Alex", age: 27, gender: "male"} , id: 24}],
total: 2}
}
/*
[[[Gloria, 24, female], 025],
[[Alex, 27, male], 024] */
const result = table.data.items.map((data) => {
const newArr = [];
newArr.push(data.id)
const {age,gender,name} = data.students
const secondArr = [name,age,gender];
newArr.push(secondArr)
return newArr
});
console.log(result);

Can use Array.map() and callback function to achive that.
But will be a little differnet to this format
[[{Gloria, 24, female}, 025],
[{Alex, 27, male}, 024]
example:
const table = {
index: 0,
data: {
items:[
{students: {name: "Gloria", age: 24, gender: "female"} , id: 25},
{students: {name: "Alex", age: 27, gender: "male"} , id: 24}],
total: 2}
}
const result = table.data.items.map((x) => {
let studentArray = [x.students.name, x.students.gender];
return [studentArray, x.id];
});
console.log(result);
console.log(result[0]);
console.log(result[1]);

Related

Map + filter - Showing people that have < 18 years and abbreviate names

I wanted to be able to transform the age into a single array, so I would already know how to filter, then apply the mapping to only show people over 18 years old, in addition, to present the abbreviated names of the people.
Example:
name: "Raul", age: 27,
name: "Jose", age: 14,
name: "Maria", age: 52,
name: "Jesus", age: 17,
name: "Neo", age: 2
[Ra, Ma] -> Those are above 18, and their names go abbreviated
Here what i tried to do:
const amantesGatos = {
name: "Raul", age: 27,
name: "Jose", age: 14,
name: "Maria", age: 52,
name: "Jesus", age: 17,
name: "Neo", age: 2
};
// this needs to be filtered
const idade = amantesGatos.age
//i tried to destructuring this array
const nomeAbrev = [amantesGatos.map(n=>n[0] + n[1])]
//Tried to abbreviated names
//Filter above 18
const array = [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 444, 17];
function above18(num) {
for (let i = 18; num < i; i--) {
if (num < i) {
return false;
}
}
return num;
}
console.log(array.filter(above18));
If I'm understanding correctly the desired outcome is [Ra, Ma]?
If so you can .filter.map.
const peeps = [
{name: "Raul", age: 27,},
{name: "Jose", age: 14,},
{name: "Maria", age: 52,},
{name: "Jesus", age: 17,},
{name: "Neo", age: 2}
]
const ofAgePeeps = peeps.filter(({age}) => age > 18)
const shortNames = ofAgePeeps.map(({name}) => name.substring(0,2))
You can also chain these...
peeps.filter(({age}) => age > 18).map(({name}) => name.substring(0,2))
That said your amantesGatos is an object with a bunch of duplicate keys and not an array. Which means it's really an object with only the last name and age. For example...
const obj = {
name: 'Tom', age: 2, name: 'Bob', age: 100
}
console.log(obj) // {name: 'Bob', age: 100}
You can do as following
let users = [
{ name: "Raul", age: 27,},
{name: "Jose", age: 14,},
{name: "Maria", age: 52,},
{name: "Jesus", age: 17,},
{name: "Neo", age: 2},
]
let data = users.filter(user => user.age > 18).map(user => user.name.slice(0, 2))
data would be [ 'Ra', 'Ma' ]

Compare two array of objects based on only matching properties

I have two array of objects
this.originalData = [
{age: 27, name: "sachin", id: 1, sex: "male", dept: "angular"},
{age: 22, name: "pooja", id: 2, sex: "female", dept: "java"},
{age: 50, name: "john", id: 3, sex: "male", dept: "sales"}
]
this.updatedData = [
{id: 1, name: "sachin", age: 25, sex: "male"},
{id: 2, name: "pooja", age: 22, sex: "female"},
{id: 3, name: "john", age: 50, sex: "male"}
]
As we can see the order and number of properties is different in both the arrays. Here, how can I do the comparison for only matching properties whether any of it is changed. In the above example, I need to get the object with id 1 from updatedData as the age property is changed from 27 to 25 when compared with originalData. The properties which are not matching can be ignored.
I tried like below but it is not working due to the differences
if(JSON.stringify(this.updatedData) !== JSON.stringify(this.originalData)) {
console.log('changed!');
}
Please suggest. Thanks.
const originalData = [
{ age: 27, name: "sachin", id: 1, sex: "male", dept: "angular" },
{ age: 22, name: "pooja", id: 2, sex: "female", dept: "java" },
{ age: 50, name: "john", id: 3, sex: "male", dept: "sales" }
]
const updatedData = [
{ id: 1, name: "sachin", age: 25, sex: "male" },
{ id: 2, name: "pooja", age: 22, sex: "female" },
{ id: 3, name: "john", age: 50, sex: "male" }
]
const output = updatedData.filter(uData => {
const commonDataRow = originalData.find(oData => oData.id === uData.id); /** filter out common entry between both arrays based on id */
const allPropertiesAreSame = Object.keys(commonDataRow).every(oDataEntry => /** iterate through the list of properties of common entry */
/**
* if the updatedData object has the properties, check if the values are same for both the objects and return appropriately,
* else ignore the property (by returning false)
*/
uData.hasOwnProperty(oDataEntry) ?
commonDataRow[oDataEntry] === uData[oDataEntry] : true
);
/** if all properties are same, return false (as we desire to filter out those entries which have at least one unmatching property) */
return !allPropertiesAreSame;
});
/**
* print the output
* the output will contain the list of objects matching the above criteria
* format it to get the list of ID's
*/
console.log(output);
The following code-snippet gives you all the items, where data has changed (ignoring keys which do not exist in either of them).
let originalData = [
{age: 27, name: "sachin", id: 1, sex: "male", dept: "angular"},
{age: 22, name: "pooja", id: 2, sex: "female", dept: "java"},
{age: 50, name: "john", id: 3, sex: "male", dept: "sales"}
];
let updatedData = [
{id: 1, name: "sachin", age: 25, sex: "male"},
{id: 2, name: "pooja", age: 22, sex: "female"},
{id: 3, name: "john", age: 50, sex: "male"}
];
let changedList = [];
originalData.map((item)=> {
let temp = (updatedData.filter((x) => item.id === x.id ))[0];
let same = true;
if((item.age && temp.age) && (item.age !== temp.age)) {same = false}
if((item.name && temp.name) && (item.name !== temp.name)) {same = false}
if((item.sex && temp.sex) && (item.sex !== temp.sex)) {same = false}
if((item.dept && temp.dept) && (item.dept !== temp.dept)) {same = false}
if(same === false) {changedList.push(item)};
console.log(same);
});
console.log(changedList);

I have an array of objects and will like to alter the value if the type is a number

I have this so far, but when I check people after it doesn't alter the age keys values to prepend "$".I want to assume I dont know which values are of type of number, so I want to do a check and change it to have $23, $3, $8 etc.
const people = [
{name: 'John', age: 23, sex: "male"},
{name: 'Andrew', age: 3, sex: "male"},
{name: 'Peter', age: 8, sex: "male"},
{name: 'Hanna', age: 14, sex: "male"},
{name: 'Adam', age: 37, sex: "male"}];
let indVals;
people.forEach(function(arr) {
indVals = Object.values(arr);
console.log('Individual values: ',indVals);
for(let val of indVals) {
if ( typeof val === "number") {
val = "$" + val;
}
}
});
You can map the people array and conditionally modify the value of a property in an object. Note that using map will give you a new array.
const people = [
{name: 'John', age: 23, sex: "male"},
{name: 'Andrew', age: 3, sex: "male"},
{name: 'Peter', age: 8, sex: "male"},
{name: 'Hanna', age: 14, sex: "male"},
{name: 'Adam', age: 37, sex: "male"}];
const result = people.map(obj => {
return Object.fromEntries(Object.entries(obj).map(([k, v]) => {
return (typeof v === 'number') ? [k, `$${v}`] : [k, v];
}));
});
console.log(result)
Since op stated that property names are not known. You need to use keys to get the properties then check the type and then update the value using the key.
const people = [
{name: 'John', age: 23, sex: "male"},
{name: 'Andrew', age: 3, sex: "male"},
{name: 'Peter', age: 8, sex: "male"},
{name: 'Hanna', age: 14, sex: "male"},
{name: 'Adam', age: 37, sex: "male"}];
people.forEach(obj=> {
Object.keys(obj).forEach(key=>{
if (typeof obj[key] === "number") {
obj[key] = "$" + obj[key];
}
});
});
console.log(people);
res = people.map((elem) => {
for(let key in elem){
if(typeof elem[key] == 'number'){
elem[key] += '$';
}
}
return elem;
})

Filter an array of objects with multiple elements with their values using javascript or lodash

I have an array of object as below.
const data =
[
{id: 1, name: 'Peter',age: 21, gender: 'Male'},
{id: 2, name: 'Steve',age: 24, gender: 'Male'},
{id: 3, name: 'John',age: 21, gender: 'Male'},
{id: 4, name: 'Julie',age: 26, gender: 'Female'}
]
I want to dynamically filter the above array with multiple elements with their values using javascript or lodash. If i add more elements to the object and try to filter with the same, the code should work fine. I'm expecting to pass the elements which needs to be filtered and the corresponding values, from an object as below.
const filter = {'name':'e','gender':'mal'}
Expected Output:
[{id: 1, name: 'Peter',age: 21, gender: 'Male'},
{id: 2, name: 'Steve',age: 24, gender: 'Male'},
{id: 4, name: 'Julie',age: 26, gender: 'Female'}]
You could filter by using the entries and Array#every for using all filters or Array#some for having only one filter property of the object.
const
data = [{ id: 1, name: 'Peter', age: 21, gender: 'Male' }, { id: 2, name: 'Steve', age: 24, gender: 'Male' }, { id: 3, name: 'John', age: 21, gender: 'Male' }, { id: 4, name: 'Julie', age: 26, gender: 'Female' }],
filter = { name: 'Pe', gender: 'Mal' },
filters = Object.entries(filter),
result1 = data.filter(o => filters.every(([k, v]) => o[k].includes(v))),
result2 = data.filter(o => filters.some(([k, v]) => o[k].includes(v)));
console.log(result1);
console.log(result2);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Use Object.entries to separate the keys and values from the filter object, find the value by using the key and lowerCase that value since you don't differentiate between uppercase and lowercase letters
const data =
[
{id: 1, name: 'Peter',age: 21, gender: 'Male'},
{id: 2, name: 'Steve',age: 24, gender: 'Male'},
{id: 3, name: 'John',age: 21, gender: 'Male'},
{id: 4, name: 'Julie',age: 26, gender: 'Female'}
]
const filter = {
'name': 'e',
'gender': 'mal'
}
const result = data.filter(x => Object.entries(filter)
.every(([key, val]) => x[key].toString().toLowerCase().includes(val)))
console.log(result)

JavaScript - sort array of objects, by a property based on a special order

I have an array of objects with multiple properties. Given the following array:
var people = [
{name: "allen", age: 33, color:"green"},
{name: "jon", age: 23, color:"blonde"},
{name: "silver", age: 54, color:"yellow"},
{name: "james", age: 52, color:"grey"},
{name: "flint", age: 25, color:"pink"},
{name: "beilly", age: 31, color:"blonde"},
{name: "bwones", age: 47, color:"grey"},
{name: "sas", age: 35, color:"green"},
{name: "jackson", age: 234, color:"yellow"},
{name: "leonsardo", age: 12, color:"brown"},
{name: "dicaeprio", age: 73, color:"pink"},
{name: "sylvfester", age: 35, color:"blonde"},
{name: "alleen2", age: 33, color:"green"},
{name: "jofn2", age: 23, color:"blonde"},
{name: "sdilver2", age: 54, color:"yellow"},
{name: "jamaes2", age: 52, color:"grey"}
];
I need to sort this array by color property, but in a special manner, first by green, then by yellow, then by brown then by pink, then grey and lastly by blonde. I read here and here, but having hard time to generate a compactor based upon my needs. Since this is just a demo array and my real data will be a much larger arrays, the sorting mechanism should be quicker than n^2.
Here is your comparator
var sortOrder = {green: 0, yellow: 1, brown: 2, pink: 3, grey: 4, blonde: 5};
people.sort(function (p1, p2) {
return sortOrder[p1.color] - sortOrder[p2.color];
});
I suggest to use a default value as well for sorting, depending where the non listed color should be sorted.
In this case the properties of the sort order object have to start with a value above zero.
colorOrder = { green: 1, yellow: 2, brown: 3, pink: 4, grey: 5, blonde: 6 };
people.sort(function (a, b) {
return (colorOrder[a.color] || 0) - (colorOrder[b.color] || 0);
});
Use Andrey method, add just one param in your object :
var sortOrder = {green: 0, yellow: 1, brown: 2, pink: 3, grey: 4, blonde: 5};
people.sort(function (p1, p2) {
return sortOrder[p1.color] - sortOrder[p2.color];
});
Or if you really can't use that, create your sort function :
var people =
[
{name: "allen", age: 33, color:"green"},
{name: "jon", age: 23, color:"blonde"},
{name: "silver", age: 54, color:"yellow"},
{name: "james", age: 52, color:"grey"},
{name: "flint", age: 25, color:"pink"},
{name: "beilly", age: 31, color:"blonde"},
{name: "bwones", age: 47, color:"grey"},
{name: "sas", age: 35, color:"green"},
{name: "jackson", age: 234, color:"yellow"},
{name: "leonsardo", age: 12, color:"brown"},
{name: "dicaeprio", age: 73, color:"pink"},
{name: "sylvfester", age: 35, color:"blonde"},
{name: "alleen2", age: 33, color:"green"},
{name: "jofn2", age: 23, color:"blonde"},
{name: "sdilver2", age: 54, color:"yellow"},
{name: "jamaes2", age: 52, color:"grey"}
];
var order = ['green','yellow','brown','pink','grey','blonde'];
function mySort(array)
{
var list = [];
function getElem(array,id)
{
for(var i in array) if(array[i].color == id) list.push(array[i])
}
for(var i in order) getElem(array,order[i]);
return list;
}
mySort(people);
I guess the proper way of doing this job is by a hash and sort but without using sort the following code might as well turn out to be pretty efficient.
var people = [
{name: "allen", age: 33, color:"green"},
{name: "jon", age: 23, color:"blonde"},
{name: "silver", age: 54, color:"yellow"},
{name: "james", age: 52, color:"grey"},
{name: "flint", age: 25, color:"pink"},
{name: "beilly", age: 31, color:"blonde"},
{name: "bwones", age: 47, color:"grey"},
{name: "sas", age: 35, color:"green"},
{name: "jackson", age: 234, color:"yellow"},
{name: "leonsardo", age: 12, color:"brown"},
{name: "dicaeprio", age: 73, color:"pink"},
{name: "sylvfester", age: 35, color:"blonde"},
{name: "alleen2", age: 33, color:"green"},
{name: "jofn2", age: 23, color:"blonde"},
{name: "sdilver2", age: 54, color:"yellow"},
{name: "jamaes2", age: 52, color:"grey"}
],
arrays = [green, yellow, brown, pink, grey, blonde] = [[],[],[],[],[],[]],
result = [];
Object.keys(people).forEach(k => this[people[k].color].push(people[k]));
result = arrays.reduce((p,c) => p.concat(c));
console.log(result);
For an improved performance you might replace the last line with
result = arrays.reduce((p,c) => (Array.prototype.push.apply(p,c),p));

Categories