Object version of mapping - javascript

Duplicate of: map function for objects (instead of arrays)
How do i map or iterate through an object where the values is another object as such:
[{
"id":2,
"name":"Jane Smith",
"position":"Cook",
"applied":"02/08/16",
"experience":4,
"availability":{
"M":1,
"T":1,
"W":1,
"Th":1,
"F":0,
"S":0,
"Su":0
},
"questions": [{
"text":"Have you ever been convicted of a felony?",
"answer":"Yes"
}]
},
...(2 other objects with the same format)....
]
I need to access the availability object

Beware that there is no guarantee of the order of an object's keys, so there is no perfectly consistent way to iterate over them. However, you can use the for...in statement to iterate over the enumerable properties of an object. You can use that to basically iterate through they key/value pairs of an objects and do something with them.
const availability = {
"M":1,
"T":1,
"W":1,
"Th":1,
"F":0,
"S":0,
"Su":0
};
for (const key in availability) {
console.log(key, availability[key]);
}
// Output:
/*
M 1
T 1
W 1
Th 1
F 0
S 0
Su 0
*/
Since it is unclear exactly how you want to use the data I can't provide any more detail than that but it should get you started.

The map() equivalent of object is Object.keys() and Object.entries()
It is a feature introduced in ES7
const data = [{
"id":2,
"name":"Jane Smith",
"position":"Cook",
"applied":"02/08/16",
"experience":4,
"availability":{
"M":1,
"T":1,
"W":1,
"Th":1,
"F":0,
"S":0,
"Su":0
},
"questions": [{
"text":"Have you ever been convicted of a felony?",
"answer":"Yes"
}]
}
]
console.log(Object.entries(data[0].availability));
console.log(Object.keys(data[0].availability));
Check this here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
For your data if you have more than one object then you can first iterate through the array first using array.map() and use Object.entries() inside map()

I assume you want a list of availability objects.
const availabilityObjects = objects.map(object => object.availability)
Will do it. Code snippet follows:
const objects = [{
"id": 2,
"name": "Jane Smith",
"position": "Cook",
"applied": "02/08/16",
"experience": 4,
"availability": {
"M": 1,
"T": 1,
"W": 1,
"Th": 1,
"F": 0,
"S": 0,
"Su": 0
},
"questions": [{
"text": "Have you ever been convicted of a felony?",
"answer": "Yes"
}]
},
{
"id": 2,
"name": "Jane Smith",
"position": "Cook",
"applied": "02/08/16",
"experience": 4,
"availability": {
"M": 1,
"T": 1,
"W": 1,
"Th": 1,
"F": 0,
"S": 0,
"Su": 0
},
"questions": [{
"text": "Have you ever been convicted of a felony?",
"answer": "Yes"
}]
},
{
"id": 2,
"name": "Jane Smith",
"position": "Cook",
"applied": "02/08/16",
"experience": 4,
"availability": {
"M": 1,
"T": 1,
"W": 1,
"Th": 1,
"F": 0,
"S": 0,
"Su": 0
},
"questions": [{
"text": "Have you ever been convicted of a felony?",
"answer": "Yes"
}]
}
]
console.log(objects.map(object => object.availability))

Related

Remove the first bracket from nested array

I have an array as follow:
let data =[
[
{
"Id": "110d611c-54e4-4593-a835-def0f34ed882",
"duration": 30,
"name": "burger",
"price": 10,
}
],
[
{
"Id": "edc241e9-5caf-4f0b-b6ea-6cf5fc57d260",
"duration": 10,
"name": "Cake",
"price": 5,
}
]
]
I am trying to remove the first bracket to be like this:
let data =
[
{
"Id": "110d611c-54e4-4593-a835-def0f34ed882",
"duration": 30,
"name": "burger",
"price": 10,
}
],
[
{
"Id": "edc241e9-5caf-4f0b-b6ea-6cf5fc57d260",
"duration": 10,
"name": "Cake",
"price": 5,
}
]
I have trying many solutions, the most common one i have tried is using this way:
let newData = data[0]
but the result always giving me the first nested array something like this:
[
{
"Id": "110d611c-54e4-4593-a835-def0f34ed882",
"duration": 30,
"name": "burger",
"price": 10
}
]
I tried to convert it to string using JSON.stringify() then remove the bracket by doing
JSON.stringify(data).substring(1, JSON.stringify(data).length - 1);
But then when i parse it i get this error:
SyntaxError: JSON Parse error: Unable to parse JSON string
I am really stuck on what the best way to accomplish it.
thanks in advance.
You want the first element of each nested array, not the first element of the outer array. So use map().
let data = [
[{
"Id": "110d611c-54e4-4593-a835-def0f34ed882",
"duration": 30,
"name": "burger",
"price": 10,
}],
[{
"Id": "edc241e9-5caf-4f0b-b6ea-6cf5fc57d260",
"duration": 10,
"name": "Cake",
"price": 5,
}]
];
let newData = data.map(el => el[0]);
console.log(newData);
Removing the external bracket will result in an invalid javascript object.
To obtain a single array with all the objects you can use flatMap
data.flatMap(x => x)
Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap
The result that you want is not valid, instead you can get array of object using flat as:
data.flat()
let data = [
[
{
Id: "110d611c-54e4-4593-a835-def0f34ed882",
duration: 30,
name: "burger",
price: 10,
},
],
[
{
Id: "edc241e9-5caf-4f0b-b6ea-6cf5fc57d260",
duration: 10,
name: "Cake",
price: 5,
},
],
];
const result = data.flat();
console.log(result);

Node js data formatting using for loop

I have an array of object with data :
[
{
"id": 1,
"milestone": "Generated",
"phase_id": 1,
"phase": "ICP Assessment",
"activity_id": 1,
"activity": "Data Analysis",
"start_date": "2018-06-12T18:30:00.000Z",
"timeline": "3 weeks",
"responsibility": "2",
"status": "Not Started"
},
{
"id": 1,
"milestone": "Generated",
"phase_id": 1,
"phase": "ICP Assessment",
"activity_id": 2,
"activity": "Territory re-alignment",
"start_date": "2018-06-27T18:30:00.000Z",
"timeline": "2 Weeks",
"responsibility": "2",
"status": "Not Started"
},
{
"id": 2,
"milestone": "Identified",
"phase_id": 2,
"phase": "Pilot Planning",
"activity_id": 3,
"activity": "Existing ICP Discussion",
"start_date": "2018-06-27T18:30:00.000Z",
"timeline": "2 Weeks",
"responsibility": "2",
"status": "Not Started"
}
]
I want to convert this data into something like:
[
{
"id": 1,
"milestone": "Generated",
"phase":[
{
"phase_id": 1,
"phase": "ICP Assessment",
"activity"[
{
"activity_id": 1,
"activity": "Data Analysis",
"start_date": "2018-06-12T18:30:00.000Z",
"timeline": "3 weeks",
"responsibility": "2",
"status": "Not Started"
},
{
"activity_id": 2,
"activity": "Territory re-alignment",
"start_date": "2018-06-27T18:30:00.000Z",
"timeline": "2 Weeks",
"responsibility": "2",
"status": "Not Started"
}
]
}
]
},
{
"id": 2,
"milestone": "Identified",
"phase":[
{
"phase_id": 2,
"phase": "Pilot Planning",
"activity"[
{
"activity_id": 3,
"activity": "Existing ICP Discussion",
"start_date": "2018-06-27T18:30:00.000Z",
"timeline": "2 Weeks",
"responsibility": "2",
"status": "Not Started"
}
]
}
]
}
]
using node.js. just want a simple solution may be using for loop. Any help would be appreciated.
Array reduce method is there to rescue
The flow is as follows. In the array reduce initially pass an empty array in the thisArg.IN the empty array check if there exist an object whose Id is id in the main array.If not then create a new object and push to the empty array
let newData = date.reduce(function (acc, curr) {
//using findIndex to test if there exist an object whose id is same as id of main
//array of objects
let getIdIndex = acc.findIndex(function (item) {
return item.id === curr.id;
})
// if the id does not exist then create a new object with these values
if (getIdIndex === -1) {
let newObj = {
id: curr.id,
milestone: curr.milestone,
phase: [{
phase_id: curr.phase_id,
phase: curr.phase,
activity: [{
activity_id: curr.activity_id,
activity: curr.activity,
start_date: curr.start_date,
timeline: curr.timeline,
responsibility: curr.responsibility,
status: curr.status
}]
}]
}
acc.push(newObj)
}
else{
// now if the id exist you need to check if therse exist an object
// where phase id matches, then same as the above logic
let getPhaseIdIndex = acc[getIdIndex].phase.findIndex(function(item){
return item.phase_id === curr.phase_id;
})
if(getPhaseIdIndex === -1){
acc[getIdIndex].phase.push({
phase_id: curr.phase_id,
phase: curr.phase,
activity: [{
activity_id: curr.activity_id,
activity: curr.activity,
start_date: curr.start_date,
timeline: curr.timeline,
responsibility: curr.responsibility,
status: curr.status
}]
})
}
else{
acc[getIdIndex].phase[getPhaseIdIndex].activity.push(
{
activity_id: curr.activity_id,
activity: curr.activity,
start_date: curr.start_date,
timeline: curr.timeline,
responsibility: curr.responsibility,
status: curr.status
}
)
}
}
return acc;
}, []) // this empty array is thisArg, new values will be added to this
console.log(newData)
Get the full code with working demo here

Returning a new JSON object with filtered results

I'm looking to return a new JS object from an existing JS object, after filtering for some result.
Say I have the following JS object:
{ "Examples" :
[ { "id": 1, "name": "Tim", "answer": "yes"},
{ "id": 2, "name": "Jon", "answer": "no"},
{ "id": 3, "name": "Don", "answer": "yes" ] }
I want to filter through this object for all yes answers and return an object that looks like this:
{ "Examples" :
[ { "id" : 1, "name": "Tim", "answer": "yes"},
{ "id" : 3, "name": "Don", "answer": "yes"} ] }
First: that's a JavaScript object, not a JSON object. JSON is a serialization scheme.
You can filter the array with .filter():
var obj = { "Examples" :
[ { "id": 1, "name": "Tim", "answer": "yes"},
{ "id": 2, "name": "Jon", "answer": "no"},
{ "id": 3, "name": "Don", "answer": "yes" ] };
obj.Examples = obj.Examples.filter(function(entry) {
return entry.answer === "yes";
});

Create a map out of a grouped array objects

I'm using Underscore.js to map a new object array out of an existing object array but cannot really get the desired results.
Essentially I have an object array like:
[
{
"total": 5.21,
"number": 3,
"a": "Paid",
"y": 2015,
"m": 1,
"d": "2015-01-17T23:58:34.115Z"
},
{
"total": 374.65,
"number": 3,
"a": "Scheduled",
"y": 2015,
"m": 1,
"d": "2015-01-18T02:16:03.503Z"
},
{
"total": 310.84,
"number": 1,
"a": "Paid",
"y": 2015,
"m": 1,
"d": "2015-01-17T23:58:34.115Z"
},
{
"total": 284.41,
"number": 3,
"a": "Scheduled",
"y": 2015,
"m": 1,
"d": "2015-01-18T02:16:03.503Z"
}
]
which I would like to map into something like:
[
{
"key": "Paid",
"values": [
[
"2015-01-17T23:58:34.115Z",
5.21
],
[
"2015-01-17T23:58:34.115Z",
310.84
]
]
},
{
"key": "Scheduled",
"values": [
[
"2015-01-18T02:16:03.503Z",
374.65
],
[
"2015-01-18T02:16:03.503Z",
284.41
]
]
}
]
I've tried using the ._map method returns a map like this (JSFiddle):
var mapped_bill = _.map(bill, function(item) {
return {"key": item.a, "values": [item.d, item.total]}
});
console.log(JSON.stringify(mapped_bill));
/* returns:
[
{
"key": "Paid",
"values": [
"2015-01-17T23:58:34.115Z",
5.21
]
},
{
"key": "Scheduled",
"values": [
"2015-01-18T02:16:03.503Z",
374.65
]
},
{
"key": "Paid",
"values": [
"2015-01-17T23:58:34.115Z",
310.84
]
},
{
"key": "Scheduled",
"values": [
"2015-01-18T02:16:03.503Z",
284.41
]
}
]
*/
How do I group the resulting map above so that I can achieve the desired map?
You can use two _.map methods with _.groupBy:
var result = _.map(_.groupBy(data, 'a'), function(el, key) {
return {
key: key,
values: _.map(el, function(item) {
return [item.d, item.total];
})
};
});
Check the demo below.
var data = [
{
"total": 5.21,
"number": 3,
"a": "Paid",
"y": 2015,
"m": 1,
"d": "2015-01-17T23:58:34.115Z"
},
{
"total": 374.65,
"number": 3,
"a": "Scheduled",
"y": 2015,
"m": 1,
"d": "2015-01-18T02:16:03.503Z"
},
{
"total": 310.84,
"number": 1,
"a": "Paid",
"y": 2015,
"m": 1,
"d": "2015-01-17T23:58:34.115Z"
},
{
"total": 284.41,
"number": 3,
"a": "Scheduled",
"y": 2015,
"m": 1,
"d": "2015-01-18T02:16:03.503Z"
}
];
var result = _.map(_.groupBy(data, 'a'), function(el, key) {
return {
key: key,
values: _.map(el, function(item) {
return [item.d, item.total];
})
};
});
pre.innerHTML = JSON.stringify(result, null, 4);
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
<pre id="pre"></pre>
Going by your history here then it could be assumed this is actually a mongodb question even though you are just looking at the resulting JavaScript object in the question as presented.
So with the structure you mention actually being the members of a MongoDB collection then the answer to produce the the required output would be:
db.mapped.aggregate([
{ "$group": {
"_id": "$a",
"values": {
"$push": {
"$map": {
"input": { "$literal": ["A","B"] },
"as": "l",
"in": {
"$cond": [
{ "$eq": [ "$$l", "A" ] },
"$d",
"$total"
]
}
}
}
}
}}
])
So the $map operator there processes our "two element array template" provided in the $literal operator section, and "transposes" the values via the $cond "ternary" to either produce the element from "$d" where the first "A" element is matched or the element "$total" where the element is not "A" but therefore "B" as the only other logical choice.
Results in mapping an array that has the first elementof the first match and the second element as the other expected value. These can then be provided to $push, to create and "array of arrays" as requested.
Which produces from your source as a collection:
{
"_id" : "Scheduled",
"values" : [
[
"2015-01-18T02:16:03.503Z",
374.65
],
[
"2015-01-18T02:16:03.503Z",
284.41
]
]
},
{
"_id" : "Paid",
"values" : [
[
"2015-01-17T23:58:34.115Z",
5.21
],
[
"2015-01-17T23:58:34.115Z",
310.84
]
]
}
So you didn't need this post processing in JavaScript as you thought you did. Using the operators that are appropriate to match your conditions on the server side $group is all you need.

Underscorejs:How to create a new object by combining values from two objects?

I came across the following scenario
var obj1= [
{
"id": 97,
"name": "Sample1",
"classId": 751,
"gradeId": 1,
"studentId": 1
},
{
"id": 98,
"name": "Sample2",
"classId": 751,
"gradeId": 1,
"studentId": 2
},
{
"id": 97,
"name": "Sample1",
"classId": 751,
"gradeId": 2,
"studentId": 3
},
{
"id": 98,
"name": "Sample2",
"classId": 751,
"gradeId": 2,
"studentId": 4
}
]
Now ,If the id's are same,I need to combine the identical object values in the following form
var obj2=[
{
"id": 97,
"name": "Sample1",
"classId": 751,
"rating":[
{
"gradeId": 1,
"studentId": 1
}
{
"gradeId": 2,
"studentId": 3
}
]
},
{
"id": 98,
"name": "Sample2",
"classId": 751,
"rating":[
{
"gradeId": 1,
"studentId": 2
}
{
"gradeId": 2,
"studentId": 4
}
]
}
]
I am looping through all the objects and ifnthe id's are same I am creating a new object with the combined values,which i feel a little bit elaborated
Can i achieve this through underscore js in a more abstract way?
_.groupBy will do what you want, then use pick/omit to map the groups to the nested objects as you want them:
var obj2 = _.map(_.groupBy(obj1, "id"), function(group) {
var o = _.omit(group[0], "gradeId", "studentId");
o.rating = _.map(group, function(s) {
return _.pick(s, "gradeId", "studentId");
});
return o;
});

Categories

Resources