I need to check if the value of startAt is present in an object. It should return the id of that object if it's in it.
Object:
[{
"id": "1234567",
"createTimestamp": "2020",
"name": {
"action": "",
"allDay": false,
"category": "Misc",
"startAt": "05",
"title": "foo"
},
"updateTimestamp": "2020"
}]
Below is what I have so far. The filtering works but I can't access the id to return it.
<div v-for="(hour, i) in 24" :key="i">
{{ filterByHour(hour) }}
</div>
filterByHour(id) {
if (id < 10) {
id = 0 + id
}
const result = this.events.filter(item => item.name.startAt === id.toString())
return result
}
How to return the id of the object?
I think the problem is in id = 0 + id. When id is 5 this line evaluates to 5 only not 05. Change to id = '0' + id, which will convert to string.
After the filter, use the map to extract id.
const events = [
{
id: "1234567",
createTimestamp: "2020",
name: {
action: "",
allDay: false,
category: "Misc",
startAt: "05",
title: "foo"
},
updateTimestamp: "2020"
}
];
function filterByHour(id) {
if (id < 10) {
id = "0" + id;
}
const result = events
.filter(item => item.name.startAt === String(id))
.map(x => x.id);
return result;
}
console.log(filterByHour(5));
console.log(filterByHour(11));
console.log(filterByHour());
Related
I saw many answers, but I haven't been able to modify any to my need.
Object
{
"id": "476ky1",
"custom_id": null,
"name": "Reunião com o novo Gerente de Vendas - Airton",
"text_content": null,
"description": null,
"status": {
"id": "p3203621_11svBhbO"
},
"archived": false,
"creator": {
"id": 3184709
},
"time_spent": 0,
"custom_fields": [{
"id": "36c0de9a-9243-4259-ba57-bd590ba07fe0",
"name": "Comments",
"value": "dsdsdsds"
}],
"attachments": []
}
Within custom_fields, if the property name's value is Comments, update the value property.
I've tried it like this, using this approach, for example, but it doesn't produce the expected result.
const updatedComment = [{ name: "Comments", value: "The comment is updated"}];
updateNestedObj(taskData, updatedComment)
function updateNestedObj(obj, updates) {
const updateToApply = updates.find(upd => upd.id === obj.id);
if (updateToApply) {
obj.title = updateToApply.content;
obj.note = updateToApply.note;
}
// Apply updates to any child objects
for(let k in obj) {
if (typeof(obj[k]) === 'object') {
updateNestedObj(obj[k], updates);
}
}
}
You're using the wrong property names when you search updates for updateToApply, and then when assigning the value.
When you recurse on children, you need to distinguish between arrays and ordinary objects, so you can loop over the nested arrays. You also have to skip null properties, because typeof null == 'object'.
const updatedComment = [{
name: "Comments",
value: "The comment is updated"
}];
function updateNestedObj(obj, updates) {
let updateToApply = updates.find(upd => upd.name == obj.name);
if (updateToApply) {
obj.value = updateToApply.value;
}
// Apply updates to any child objects
Object.values(obj).forEach(child => {
if (Array.isArray(child)) {
child.forEach(el => updateNestedObj(el, updates));
} else if (typeof(child) === 'object' && child != null) {
updateNestedObj(child, updates);
}
});
}
const taskData = {
"id": "476ky1",
"custom_id": null,
"name": "Reunião com o novo Gerente de Vendas - Airton",
"text_content": null,
"description": null,
"status": {
"id": "p3203621_11svBhbO"
},
"archived": false,
"creator": {
"id": 3184709
},
"time_spent": 0,
"custom_fields": [{
"id": "36c0de9a-9243-4259-ba57-bd590ba07fe0",
"name": "Comments",
"value": "dsdsdsds"
}],
"attachments": []
};
updateNestedObj(taskData, updatedComment)
console.log(taskData);
Try this:
const updatedComment = [{ name: "Comments", value: "A new comment value" }]
// you can add as many updates as you want
function update(obj, updates) {
for (const update in updates) {
for (const field in obj.custom_fields) {
if (obj.obj.custom_fields.name == update.name) {
obj.obj.custom_fields.value = update.value
}
}
}
}
update(obj, updatedComment)
I have a nested json array and I am trying to get the maximum value of the points attribute in this array.
data = {
"name": "KSE100",
"children": [
{
"name": "TECHNOLOGY & COMMUNICATION",
"children": [
{
"name": "TRG",
'points': -21
},
{
"name": "SYS",
},
]
},
{
"name": "OIL",
"children": [
{
"name": "PPL",
'points': 9
},
{
"name": "PSO",
'points': -19
},
]
},
]
}
I want the max value of points from under the children sections. I mean from under technology and oil sectors.
What I've done so far:
var max;
for (var i in data.children.length) {
for (var j in data.data[i]) {
var point = data.data[i].children[j]
}
}
Try the following:
data = {
"name": "KSE100",
"children": [
{
"name": "TECHNOLOGY & COMMUNICATION",
"children": [
{
"name": "TRG",
'points': -21
},
{
"name": "SYS",
},
]
},
{
"name": "OIL",
"children": [
{
"name": "PPL",
'points': 9
},
{
"name": "PSO",
'points': -19
},
]
},
]
}
var array = [];
for (var first of data.children) {
for (var second of first.children) {
if(second.points != undefined)
{
array.push(second);
}
}
}
var maximumValue = Math.max.apply(Math, array.map(function(obj) { return obj.points; }));
console.log(maximumValue);
you can use the reduce method on the array object to do this
const maxValues = []
data.children.forEach(el => {
if (el.name === 'OIL' || el.name === 'TECHNOLOGY & COMMUNICATIO'){
const max = el.children.reduce((current, previous) => {
if (current.points > previous.points) {
return current
}
}, 0)
maxValues.append({name: el.name, value: max.points})
}
})
This will give you an array of the objects with the name and max value.
First you can convert your object to a string through JSON.stringify so that you're able to use a regular expression
(?<=\"points\":)-?\\d*
To matchAll the values preceded by the pattern \"points\": that are or not negative values. After it, convert the result to a array through the spread operator ... and then reduce it to get the max value.
const data = {name:"KSE100",children:[{name:"TECHNOLOGY & COMMUNICATION",children:[{name:"TRG",points:-21},{name:"SYS"}]},{name:"OIL",children:[{name:"PPL",points:9},{name:"PSO",points:-19}]}]};
console.log(
[ ...JSON.stringify(data).matchAll('(?<=\"points\":)-?\\d*')]
.reduce((acc, curr) => Math.max(curr, acc))
)
I wasn't 100% sure, what your exact goal is, so I included a grouped max value and and overall max value with a slight functional approach.
Please be aware that some functionalities are not working in older browsers i.e. flatMap. This should anyways help you get started and move on.
const data = {
name: "KSE100",
children: [
{
name: "TECHNOLOGY & COMMUNICATION",
children: [
{
name: "TRG",
points: -21,
},
{
name: "SYS",
},
],
},
{
name: "OIL",
children: [
{
name: "PPL",
points: 9,
},
{
name: "PSO",
points: -19,
},
],
},
],
};
const maxPointsByGroup = data.children.reduce(
(acc, entry) => [
...acc,
{
name: entry.name,
max: Math.max(
...entry.children
.map((entry) => entry.points)
.filter((entry) => typeof entry === "number")
),
},
],
[]
);
console.log("grouped max:", maxPointsByGroup);
const overallMax = Math.max(
...data.children
.flatMap((entry) => entry.children.flatMap((entry) => entry.points))
.filter((entry) => typeof entry === "number")
);
console.log("overall max:", overallMax);
I have an array called data that keeps users information. I want to filter it to return the best percentage of each user for me.how can I do this.
this is my array:
let data = [ {
"userId": "1",
"percent": 97.58,
},
{
"userId": "1",
"percent": 92.01,
},
{
"userId": "2",
"percent": 91.64,
},
{
"userId": "2",
"percent": 91.64,
},
{
"userId": "3",
"percent": 91.64,
}]
I would use reduce:
let data = [
{ "userId": "1", "percent": 97.58, },
{ "userId": "1", "percent": 92.01, },
{ "userId": "2", "percent": 91.12, },
{ "userId": "2", "percent": 91.64, },
{ "userId": "3", "percent": 91.45, }
]
const bestGrades = data.reduce((acc, cur) => {
acc[cur.userId] = acc[cur.userId] || 0; // initialise the entry
acc[cur.userId] = Math.max(acc[cur.userId],cur.percent); // take the greatest
return acc;
}, {})
console.log(bestGrades)
reduce is a useful method as it allows you to accumulate new information into a new object as you iterate over the array.
const data=[{userId:"1",percent:97.58},{userId:"1",percent:92.01},{userId:"2",percent:91.64},{userId:"2",percent:91.64},{userId:"3",percent:91.64}];
const out = data.reduce((acc, c) => {
// Grab the id and percentage from the current object
const { userId: id, percent } = c;
// If the initial object that you pass in (the accumulator)
// doesn't have a property with a key that matches the id
// set a new property with the percentage value
acc[id] = acc[id] || percent;
// If the value of the percentage of the current object
// is greater than the value set on the existing property
// update it
if (percent > acc[id]) acc[id] = percent;
// Return the accumulator for the next iteration
return acc;
}, {});
console.log(out);
Let's say, I have an Array of object:
var jsonData = [{
"Mass": "3",
"Force": "3.1",
"Acceleration": "3"
}, {
"Mass": "3",
"Force": "4.1",
"Acceleration": "3"
}, {
"Mass": "4",
"Force": "4.1",
"Acceleration": "4"
}, {
"Mass": "4",
"Force": "4.1",
"Acceleration": "4"
}, {
"Mass": "0",
"Force": "0",
"Acceleration": "0"
}, {
"Mass": "0",
"Force": "0",
"Acceleration": "0"
}];
What I want is to convert this JSON to a table like this for each of
2 objects serially where Mass and Acceleration cells are merged.
You can do this with reduce method and % operator to add element to an array on every 2nd element and then based on that new array you can build table.
var jsonData = [{"Mass":"3","Force":"3.1","Acceleration":"3"},{"Mass":"3","Force":"4.1","Acceleration":"3"},{"Mass":"4","Force":"4.1","Acceleration":"4"},{"Mass":"4","Force":"4.1","Acceleration":"4"},{"Mass":"0","Force":"0","Acceleration":"0"},{"Mass":"0","Force":"0","Acceleration":"0"}]
const result = jsonData.reduce((r, e, i, a) => {
// when index is 0, 2, 4 ... (every 2nd)
if (i % 2 == 0) {
// get also the next element 1, 3, 5
const next = a[i + 1];
// create a copy of current element and force as array
const obj = { ...e, Force: [e.Force] }
// if there is next element push its force to array
if (next) obj.Force.push(next.Force);
// push that new object to accumulator
r.push(obj)
}
return r;
}, []);
const table = $('table');
const thead = table.find('thead');
const tbody = table.find('tbody');
Object.keys(result[0]).forEach(key => {
thead.append($('<th>', {
text: key
}))
})
result.forEach(e => {
const row = $('<tr>');
row.append($('<td>', {
text: e.Mass
}));
const force = $('<td>');
e.Force.forEach(f => {
const forceRow = $("<tr>");
forceRow.append($('<td>', {
text: f
}));
force.append(forceRow);
});
row.append(force);
row.append($('<td>', {
text: e.Acceleration
}));
tbody.append(row)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table border="1">
<thead></thead>
<tbody></tbody>
</table>
I have this JSON structure:
[{
"name": "ankit",
"DOB": "23/06"
}, {
"name": "kapil",
"DOB": "26/06"
}, {
"name": "ankit",
"DOB": "27/06"
}]
I want to count similar object with value ankit. How can I do this?
You can use Array.prototype.filter():
var count = json.filter(function (el) {
return el.name == 'ankit';
}).length;
How about:
let a = [
{ "name": "ankit", "DOB": "23/06" },
{ "name": "kapil", "DOB": "26/06" },
{ "name": "ankit", "DOB": "27/06" }
];
let count = 0;
a.forEach(item => {
if (item.name === "ankit") {
count++;
}
});
(code in playground)
You could use an object for counting and get the wanted count for a name with the name as property.
var data = [{ "name": "ankit", "DOB": "23/06" }, { "name": "kapil", "DOB": "26/06" }, { "name": "ankit", "DOB": "27/06" }],
count = {};
data.forEach(function (a) {
count[a.name] = (count[a.name] || 0) + 1;
});
console.log(count);
console.log(count['ankit']);
You can use the reduce method to reduce the items that have the name ankit to a number.
var items = [
{
name: 'ankit',
DOB: '23/06'
},
{
name: 'kapil',
DOB: '26/06'
},
{
name: 'ankit',
DOB: '27/06'
}
]
var numItems = items.reduce(function (count, item) {
return item.name === 'ankit' ? count + 1 : count
}, 0)
document.write('Number of items with the name `ankit`: ' + numItems)
1. Get the object from JSON:
var obj = JSON.parse(text);
2. Get your array filtered:
var count = obj.filter(function(obj) { return obj.name == "ankit" }).length;