Object is not been read node.js - javascript

I have and object db_parsed
when I run console.log(JSON.stringify(db_parsed, null, 4))
the result is:
{
"data": [
[
{
"name": "Me",
"age": 23,
"sex": "M"
},
{
"name": "Wonderwoman",
"age": 22,
"sex": "F"
}
],
[
{
"name": "ALbert The Man",
"age": 22,
"sex": "M"
}
],
[
{
"name": "Leonard Johnson",
"age": 23,
"sex": "M"
}
]
]
}
but when I run console.log(db_parsed.data.filter(obj => obj.age === 22))
the result is []
Why? What am i missing? How do I fix this?

db_parsed.data is an array containing arrays.
That second level of arrays contains objects.
Your filter code is trying to treat those objects and being directly inside db_parsed.data instead of inside db_parsed.data[0], db_parsed.data[1] and db_parsed.data[2].
You could use reduce to concatenate all the second level of arrays into one, and then filter on that.
var db_parsed = {
"data": [
[{
"name": "Me",
"age": 23,
"sex": "M"
},
{
"name": "Wonderwoman",
"age": 22,
"sex": "F"
}
],
[{
"name": "ALbert The Man",
"age": 22,
"sex": "M"
}],
[{
"name": "Leonard Johnson",
"age": 23,
"sex": "M"
}]
]
};
console.log(db_parsed.data.reduce((a,b) => a.concat(b), []).filter(obj => obj.age === 22))

You can do [].concat.apply([], db_parsed.data) and than filter the array of objects:
const db_parsed = {"data": [[{"name": "Me","age": 23,"sex": "M"},{"name": "Wonderwoman","age": 22,"sex": "F"}],[{"name": "ALbert The Man","age": 22,"sex": "M"}],[{"name": "Leonard Johnson","age": 23,"sex": "M"}]]};
const result = [].concat.apply([], db_parsed.data).filter(obj => obj.age === 22);
console.log(result);

Related

Array reduce not giving all the data

let inputArr = [{
"gender": "MALE",
"name": "A",
"age": 20
},
{
"gender": "MALE",
"name": "B",
"age": 12
},
{
"gender": "FEMALE",
"name": "C",
"age": 16
},
{
"gender": "MALE",
"name": "D",
"age": 21
},
{
"gender": "FEMALE",
"name": "E",
"age": 30
}
]
console.log(JSON.stringify(inputArr.reduce((acc, ele) => {
if (acc[ele["gender"]]) {
acc[ele.gender].members.push(ele);
} else {
acc[ele["gender"]] = {
members: []
}
}
return acc;
}, {})))
I am trying to group users on the basis of gender ,using Array.reduce but the output is not showing all the records that are included in the array ,I am not able to understand the isssue here
Your reducer doesn't push the element when it encounter a gender for the first time, so the first user of each gender is missing from your result
let inputArr = [{"gender": "MALE","name": "A","age": 20},{"gender": "MALE","name": "B","age": 12},{"gender": "FEMALE","name": "C","age": 16},{"gender": "MALE","name": "D","age": 21},{"gender": "FEMALE","name": "E","age": 30}]
console.log(JSON.stringify(inputArr.reduce((acc, ele) => {
if (acc[ele["gender"]]) {
acc[ele.gender].members.push(ele);
} else {
acc[ele["gender"]] = {
members: [ele] // initialise the array with the current user
}
}
return acc;
}, {})))
Another solution, but I don't recommend this if performance matter.
let inputArr = [{
"gender": "MALE",
"name": "A",
"age": 20
},
{
"gender": "MALE",
"name": "B",
"age": 12
},
{
"gender": "FEMALE",
"name": "C",
"age": 16
},
{
"gender": "MALE",
"name": "D",
"age": 21
},
{
"gender": "FEMALE",
"name": "E",
"age": 30
}
]
function groupBy(array, field) {
return array.reduce((acc, item) => ({
...acc,
[item[field]]: [...acc[item[field]] || [], item]
}), {})
}
console.log(groupBy(inputArr, "gender"))

Object not replacing using spread operator

I want to replace existing object with new updated fields using spread operator. But I am not getting the correct result.
Below are my two objects.
let obj1 = [
{
"id": 1,
"name": "Michel",
"age": 34,
"email": "michel#gmail.com"
},
{
"id": 2,
"name": "Abby",
"age": 40,
"email": "abby#gmail.com"
},
{
"id": 3,
"name": "Gary",
"age": 40,
"email": "abby#gmail.com"
}
]
let newObj = {
"id": 3,
"name": "Gary",
"age": 23,
"email": "gary#gmail.com"
}
I can do it with .map. Below is my code.
let result = obj1.map(item => {
if (item.id === newObj.id) {
return {...item, ...newObj};
}
return item;
});
But I do not want to run the loop and want to acheive by spread operator only.
Example for spread. Which is not working. It's not replacing the object. Instead creating one more.
[...obj1, newObj];
Can someone help me?
JSBIN CODE SNIPPET
Spread syntax doesn't replace the object within array like you used it. Using map is the simplest and understandable way. However if you want to use spread syntax you would first need to find the index to be replaced and then use slice on array
let obj1 = [
{
"id": 1,
"name": "Michel",
"age": 34,
"email": "michel#gmail.com"
},
{
"id": 2,
"name": "Abby",
"age": 40,
"email": "abby#gmail.com"
},
{
"id": 3,
"name": "Gary",
"age": 40,
"email": "abby#gmail.com"
}
]
let newObj = {
"id": 3,
"name": "Gary",
"age": 23,
"email": "gary#gmail.com"
}
const idx = obj1.findIndex(item => item.id === newObj.id);
obj1 = [...obj1.slice(0, idx), newObj, ...obj1.slice(idx + 1)];
console.log(obj1);
Use Object.assign
The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object.
let obj1 = [
{
"id": 1,
"name": "Michel",
"age": 34,
"email": "michel#gmail.com"
},
{
"id": 2,
"name": "Abby",
"age": 40,
"email": "abby#gmail.com"
},
{
"id": 3,
"name": "Gary",
"age": 40,
"email": "abby#gmail.com"
}
]
let newObj = {
"id": 3,
"name": "Gary",
"age": 23,
"email": "gary#gmail.com"
}
Object.assign(obj1[2], newObj);
console.log(obj1)
Using .find() to get the target obj
let obj1 = [
{
"id": 1,
"name": "Michel",
"age": 34,
"email": "michel#gmail.com"
},
{
"id": 2,
"name": "Abby",
"age": 40,
"email": "abby#gmail.com"
},
{
"id": 3,
"name": "Gary",
"age": 40,
"email": "abby#gmail.com"
}
]
let newObj = {
"id": 3,
"name": "Gary",
"age": 23,
"email": "gary#gmail.com"
}
const targetObj = obj1.find(obj => obj.id === newObj.id)
Object.assign(targetObj, newObj);
console.log(obj1)
you should normalize your data by id this way:
obj1 = {
1: {
"id": 1,
"name": "Michel",
"age": 34,
"email": "michel#gmail.com"
},
2: {
"id": 2,
"name": "Abby",
"age": 40,
"email": "abby#gmail.com"
},
3: {
"id": 3,
"name": "Gary",
"age": 40,
"email": "abby#gmail.com"
}
}
newObj = {
3: {
"id": 3,
"name": "Gary",
"age": 23,
"email": "gary#gmail.com"
}
}
this way you can use spread operator:
{ ...obj1, ...newObj }
in order to normalize you can use the reduce func this way:
const normalized = obj1.reduce((result, obj) => ({ ...result, [obj.id]: obj }), {})
Spread operator is magic but it won't do whatever you want, you will have to loop over and replace the object. Instead of doing a map(), I would prefer find(). The use Object.assign() to achieve what you want.
let obj1 = [
{
"id": 1,
"name": "Michel",
"age": 34,
"email": "michel#gmail.com"
},
{
"id": 2,
"name": "Abby",
"age": 40,
"email": "abby#gmail.com"
},
{
"id": 3,
"name": "Gary",
"age": 40,
"email": "abby#gmail.com"
}
]
let newObj = {
"id": 3,
"name": "Gary",
"age": 23,
"email": "gary#gmail.com"
}
let foundOb = obj1.find(e => e.id === newObj.id);
Object.assign(foundOb, newObj)
console.log(obj1)
You cannot use spread syntax in that way. One solution would be to find index of the object you want to replace by id property and then you could use spread syntax with slice method to create new array with replaced object.
let obj1 = [{"id":1,"name":"Michel","age":34,"email":"michel#gmail.com"},{"id":2,"name":"Abby","age":40,"email":"abby#gmail.com"},{"id":3,"name":"Gary","age":40,"email":"abby#gmail.com"}]
let newObj = {"id":3,"name":"Gary","age":23,"email":"gary#gmail.com"}
const index = obj1.findIndex(({id}) => id == newObj.id)
const result = [...obj1.slice(0, index), newObj, ...obj1.slice(index + 1)]
console.log(result)
I would do something like:
updatedObj = [obj1.map((entry) => entry.id !== newObj.id), newObj]
This would give me the updated object with minimal syntax

Find object index from array

I'm trying to find out selected object index from array
But it always return -1 don't know why?
Here is I'm trying to do
I have following array in which their are multiple objects
var data = [{
"name": "abc",
"age": 25,
"school": "xyz pqr"
},
{
"name": "abc1",
"age": 26,
"school": "xyz pqr"
},
{
"name": "abc2",
"age": 27,
"school": "xyz pqr"
}]
And here is my another array that are selected by user
var dList = [{
"name": "abc",
"age": 25,
"school": "xyz pqr",
"isChecked": true
}]
Now I want to find out selected object index from data array and remove this object from that array
if (dList.length > 0) {
for (let i=0; i<dList.length; i++){
delete dList[i]['isChecked']
console.log(dList[i])
console.log(data[0])
console.log(dList[i] == data[0])
let index = data.indexOf(dList[i]);
console.log(index)
data.splice(index, 1);
}
}
Here is just a simple implementation:
if (dList.length > 0) {
for (let i=0; i<dList.length; i++) {
delete dList[i]['isChecked']
console.log(dList[i])
console.log(data[0])
console.log(JSON.stringify(dList[i]) === JSON.stringify(data[0]))
let index = data.findIndex(()=>dList[i]);
console.log(index)
data.splice(index, 1);
}
}
Comparing the objects can be done by just converting it into string using JSON.stringify(ObjectName).
Second instead of using indexOf use findIndex.
Here is the main difference between indexOf and findIndex.
You can only compare two primitive types only so you will not be able to get the index of the object by comparing it.
You should instead compare some primary key which will be unique for each object inside the array.
var data = [{
"name": "abc",
"age": 25,
"school": "xyz pqr"
},
{
"name": "abc1",
"age": 26,
"school": "xyz pqr"
},
{
"name": "abc2",
"age": 27,
"school": "xyz pqr"
}];
var index = data.findIndex(x => x.name=="abc2");
console.log(index);
this is going to meet your demand, a more universal version,if you got unique id,that is going to be the best choice:
var data = [{
"name": "abc",
"age": 25,
"school": "xyz pqr"
},
{
"name": "abc1",
"age": 26,
"school": "xyz pqr"
},
{
"name": "abc2",
"age": 27,
"school": "xyz pqr"
}
];
var dList = [{
"name": "abc",
"age": 25,
"school": "xyz pqr",
"isChecked": true
}];
dList.forEach(function(obj) {
delete obj.isChecked;
data.splice(data.findIndex((o) => {
return Object.getOwnPropertyNames(obj).every(p => obj[p] === o[p]);
}), 1);
});
console.log(data);
another way:
var data = [{
"name": "abc",
"age": 25,
"school": "xyz pqr"
},
{
"name": "abc1",
"age": 26,
"school": "xyz pqr"
},
{
"name": "abc2",
"age": 27,
"school": "xyz pqr"
}
];
var dList = [{
"name": "abc",
"age": 25,
"school": "xyz pqr",
"isChecked": true
}];
dList.forEach(function(obj) {
delete obj.isChecked;
data.splice(data.findIndex((o) => o.name === obj.name && o.age === obj.age && o.school === obj.school && o.school === obj.school), 1);
});
console.log(data);
unrecommended way:
var data = [{
"name": "abc",
"age": 25,
"school": "xyz pqr"
},
{
"name": "abc1",
"age": 26,
"school": "xyz pqr"
},
{
"name": "abc2",
"age": 27,
"school": "xyz pqr"
}
];
var dList = [{
"name": "abc",
"age": 25,
"school": "xyz pqr",
"isChecked": true
}];
dList.forEach(function(obj) {
delete obj.isChecked;
data.splice(data.findIndex((o) => JSON.stringify(o) === JSON.stringify(obj)), 1);
});
console.log(data);
You can use this also
var data = [{
"name": "abc",
"age": 25,
"school": "xyz pqr"
},
{
"name": "abc1",
"age": 26,
"school": "xyz pqr"
},
{
"name": "abc2",
"age": 27,
"school": "xyz pqr"
}];
var dList = [{
"name": "abc",
"age": 25,
"school": "xyz pqr",
"isChecked": true
}]
console.log(data.map(function(d){
return d.name;
}).indexOf(dList[0].name));
You cannot compare two Object Notations(JSON). To compare two JSONs you need to first stringify the object, then JavaScript can compare the two objects for you.
Here is a simple code for you to get what you desire.
if (dList.length > 0) {
for(var i=0; i<data.length; i++){
for(var j=0; j<dList.length; j++){
delete dList[j]['isChecked'];
if(JSON.stringify(data[i]) === JSON.stringify(dList[j])){
let index = data.indexOf(data[i]);//Gets the index of the array
data.splice(index, 1);
console.log(data);
}else{
console.log('Data Not Matched in Array');
}
}
}
}
There is no generic means to determine that an object is equal to another in the sense. Please see Equality comparisons for more information.
You can find and remove objects like below:
Array.prototype.remove = function(elem) {
var indexElement = this.findIndex(el => el.name === elem.name);
console.log(indexElement);
if (indexElement != -1)
this.splice(indexElement, 1);
return this;
};
data.remove(dList[0]);
console.log(data);
Online demo (jsFiddle)
var result= data.filter((item, i, self) => {
if (item.name === 'abc2') {
return { itemIndex: i, obj: item }
}
});
var output = result.map(r => { console.log(r.itemIndex) })
console.log(output);
This will return all objects in which name is abc2. findIndex array method will always return 1 index that might not be the case as people can have the same name.

How to reduce and filter arrays in javascript?

So I want to filter my array as followed:
Lets say my array1 = ['c', 'd']
My data array =
[{
"userid": "a",
"age": 19,
"name": "john"
}, {
"userid": "c",
"age": 119,
"name": "joy"
}, {
"userid": "d",
"age": 119,
"name": "jesse"
}]
I want to filter out my data array so that only those objects in data array are there whose userid values are present in array1.
Expected result:
new data array = [{
"userid": "c",
"age": 119,
"name": "joy"
}, {
"userid": "d",
"age": 119,
"name": "jesse"
}]
To make you understand better, adding Tushar's solution without lambda expression,
newDataArray = dataArray.filter(function(item) {return array1.includes(item.userid)})
In ES5:
var newDataArray = dataArray.filter(function (item) {
return array1.indexOf(item.userid) !== -1;
});
var a1 = [
{
"userid": "a",
"age": 19,
"name": "john"
},
{
"userid": "c",
"age": 119,
"name": "joy"
},
{
"userid": "d",
"age": 119,
"name": "jesse"
}
];
var a2 = ['c','d'];
var newObj = [];
a1.filter(function(object,index){
var x = object.userid;
a2.filter(function(userId){
if(x==userId){
newObj[index-1] = object;
}
});
});
console.log(JSON.stringify(newObj));

How to sort a multidimensional object in JavaScript [duplicate]

This question already has answers here:
Sorting Object by sub-object property
(4 answers)
Closed 7 years ago.
How to sort the objects by age value?
I have the following object structure
{
"men": {
"20114": {
"id": "20114",
"name": "Peter",
"age": "21"
},
"28957": {
"id": "28957",
"name": "Paul",
"age": "20"
}
},
"women": {
"8957": {
"id": "8957",
"name": "Rose",
"age": "24"
},
"2178": {
"id": "2178",
"name": "Sara",
"age": "22"
}
},
}
I know, that I can sort arrays like this
groups.sort(function(a, b) {
return b.age - a.age;
});
but how to do this with objects?
It would be a lot easier to sort your data if you could change your structure to the JSON model below:
var data = [
{
"id": "20114",
"name": "Peter",
"age": "21",
"gender": "men"
},
{
"id": "28957",
"name": "Paul",
"age": "20",
"gender": "men"
},
{
"id": "8957",
"name": "Rose",
"age": "24",
"gender": "women"
},
{
"id": "2178",
"name": "Sara",
"age": "22",
"gender": "women"
}
]
data.sort(function(a, b) {
return parseFloat(a.age) - parseFloat(b.age);
});
data.sort()
document.write(JSON.stringify(data))
function sortfunc(prop){
return function(obj1,obj2){
var val1 = obj1[prop];
var val2 = obj2[prop];
return val1 - val2;
};
}
groups.sort(sortfunc(prop));
pass prop as property name

Categories

Resources