I am working on a small VueJS webapp. I would like to output data from my array to the view but it has to be the last item of an array and of that last item the second item which is a and in my example equel to 39. I don't know how I can recieve that one.
HTML
<p>The last number in the array (a) is {{userLastCount}} </p>
Javascript/Vue
data () {
return {
event: 'Custom event',
userLastCount: 0,
lineData: [
{ time: '2017-05-01 15:00', a: 0 },
{ time: '2017-05-01 16:00', a: 12 },
{ time: '2017-05-01 17:00', a: 23 },
{ time: '2017-05-01 18:00', a: 28 },
{ time: '2017-05-01 19:00', a: 39 },
]
}
},
components: {
DonutChart, BarChart, LineChart, AreaChart
},
created() {
this.userLastCount = //equal to 39
}
I would like to output the last value of 'a' of the lineData object and assign it to a data string which I can output to the view. So, now the last 'a' = 39. But if I add another row in my object It has to be that one that is assigning to this.userLastCount
The last item of an array is arr[arr.length - 1]. You can use a computed to have that value always set for you, rather than maintaining a data item yourself:
computed: {
userLastCount() {
return this.lineData[this.lineData.length - 1].a;
}
}
Ypu can do this uzing plain javascript
In your created() hook do as follows:
created(){
//get the position of last object in the array.
var lastPosition = this.lineData.length -1;
this.userLastCount = this.lineData[lastPosition].a;
}
Related
I have an array with over 50 entries in the form of objects, which I would like to save depending on the Item ID so that I can then apply certain calculations to them. For example, I would like to add up the time of all entries with the Item Id "Las5241Wz".
Since the array can change dynamically, I can't analyze it manually. How can I separate the data beforehand according to their Item ID and push them into new arrays? The real Array contains up to 16 objects with the same ID.
var data= []
data = [
//...objects
{
itemId: "Las5241Wz",
time: 10
},
{
itemId:"Bos1239Zf",
time: 11
},
{
itemId:"Las5241Wz",
time: 15
},
{
itemId:"Bos1239Zf",
time: 21
}
//...more objets
]
The solution for this should look like this:
var Item1 = [
{
itemId: "Las5241Wz",
time: 10
},
{
itemId:"Las5241Wz",
time: 15
},
]
var Item2 = [
{
itemId:"Bos1239Zf",
time: 11
},
{
itemId:"Bos1239Zf",
time: 21
}
]
Here is another solution that builds an object with the properties "item1", "item2" and so on from the given object:
const data = [
//...objects
{
itemId: "Las5241Wz",
time: 10
},
{
itemId:"Bos1239Zf",
time: 11
},
{
itemId:"Las5241Wz",
time: 15
},
{
itemId:"Bos1239Zf",
time: 21
}
//...more objets
]
console.log(
Object.values(
data.reduce((o,e)=>((o[e.itemId]=o[e.itemId]||[]).push(e),o),{}))
.reduce((o,c,i)=>(o["item"+(i+1)]=c,o),{})
);
This is a "one-liner" and for that reason not that easy to read. So, probably not the version you would put into your production code.
Unless you have a performance reason to keep the lists separately, the answer is that you can just store the list of ids as a Set and use array.filter when you want to get the list that is just for that id
Set s = new Set();
for (let i = 0; i < data.length; i++) {
s.add(data[i].itemId);
}
var createFilterFunc(id) {
return function(elem) {
return elem.itemId == id;
}
}
var items = data.filter (createFilterFunc("Las5241Wz"));
Lets say I have this array of objects:
const arrayOfObjects = [
{ task: "work", time: 1 },
{ task: "travel", time: 4 },
{ task: "work", time: 5 },
{ task: "eat", time: 3 },
{ task: "eat", time: 1 },
{ task: "eat", time: 5 }
];
and I want to return a single objects that returns each key as the task and each value as the sum of all values of the key.
for example, the produced object of the array above should be:
sumOfObejcts = {
work: 6,
travel: 4,
eat: 9
}
How can I do it properly with reduce function?
I don't know how to sum all the items of specific key, this is what I made after few tries from examples:
const sumOfObejcts = arrayOfObjects.reduce((acc, items) => {
let { task, time } = items;
return { ...acc, [task]: [...(acc[task] || []), time] };
}, {});
and the output I get is:
{
work: [1, 5],
travel: [4],
eat: [3, 1, 5]
}
So, I just want to return the sum of occurrence of the value instead.
Your solution is very close; except that you're creating array of values on each iteration, instead of summing the current time values.
Here I've changed the value you assign to the key by using a ternary statement. This checks to see if the task exists in the accumulator object; if the task already exists, that means there is already a sum for this task and thus we just need to add on the current time to the existing sum. Otherwise, if the accumulator object doesn't have the task, the value will be primed using the current task's time.
const sumOfObjects = arrayOfObjects
.reduce((acc, item) =>
({ ...acc, [item.task]: (
acc[item.task] // does the task exist in the accumulator object?
? acc[item.task] + item.time // if so, set a value equal to the current task's time plus the existing value
: item.time // otherwise, prime the task's value to the current time
) })
, {});
Use forEach and build the object
const sumOfObjects = (arr, all = {}) => (
arr.forEach(({ task, time }) => (all[task] = (all[task] ?? 0) + time)), all
);
const arrayOfObjects = [
{ task: "work", time: 1 },
{ task: "travel", time: 4 },
{ task: "work", time: 5 },
{ task: "eat", time: 3 },
{ task: "eat", time: 1 },
{ task: "eat", time: 5 },
];
console.log(sumOfObjects(arrayOfObjects));
I'm trying to render a chart from a big amount of data (about 1200 entries). The chart takes in an array of objects with text and value properties like the one shown in FIG1. The data that I have coming in though is an object with key value pairs of string and number like the one shown if FIG2.
How could I transform the data from FIG2 format to FIG1 format so that I can use it in the Chart? Any help is much appreciated.
//FIG1
let words = [
{
text: "told",
value: 64,
},
{
text: "great",
value: 11,
},
{
text: "thought",
value: 16,
},
{
text: "clean",
value: 17,
},
];
//FIG2
const data = {
"give it a try!": 97,
"go for 6 months and get 1 month free": 8,
"go for 12 months and get 2 month free": 2,
"go for 12 months and get 2 months free": 6,
"go to url": 1,
};
...
return (
<div>
<h1>Chart</h1>
<ReactWordcloud words={words} />
</div>
);
Easy-Peasy
const transformed = Object.entries(data).map(( [key, value] )=>{
return { text:key , value: value }
})
I have an array of objects that contain a date and an amount (among other things).
There is an object for each date with a specific amount, but there can also be multiple objects for the same date containing different amounts.
I'd like to consolidate the objects so I only have one object in the array for each date ... and have the amount corresponding to that date be the total sum of all previous amounts in those objects.
Examples will probably help here:
What my array looks like now:
[
{
date: "2019-1-1", // this is a dupe date
amount: 20,
...
},
{
date: "2019-1-1", // this is a dupe date
amount: 40,
...
},
{
date: "2019-1-2",
amount: 40,
...
},
{
date: "2019-1-3",
amount: 40,
...
}
]
What I would like my array to look like:
[
{
date: "2019-1-1", // this is now a unique date
amount: 60, // and the amount was totaled
...
},
{
date: "2019-1-2",
amount: 40,
...
},
{
date: "2019-1-3",
amount: 40,
...
}
]
Use .reduce to reduce an array into an object (or into anything else) by iterating over its properties. You just need to test to see if an object with a matching date already exists in the accumulator first:
const input = [
{
date: "2019-1-1", // this is a dupe date
amount: 20,
foo: 'bar',
},
{
date: "2019-1-1", // this is a dupe date
amount: 40,
foo: 'bar',
},
{
date: "2019-1-2",
amount: 40,
foo: 'bar',
},
{
date: "2019-1-3",
amount: 40,
foo: 'bar',
}
];
const output = input.reduce((accum, item) => {
const { date, amount } = item;
const foundObj = accum.find(({ date: findDate }) => findDate === date);
if (foundObj) {
foundObj.amount += amount;
return accum;
}
accum.push(item);
return accum;
}, []);
console.log(output);
You may do as follows;
var data = [ { date: "2019-1-1", // this is a dupe date
amount: 20},
{ date: "2019-1-1", // this is a dupe date
amount: 40},
{ date: "2019-1-2",
amount: 40},
{ date: "2019-1-3",
amount: 40}
],
result = Object.values(data.reduce((r,d) => r[d.date] ? (r[d.date].amount += d.amount, r)
: (r[d.date] = d, r), {}));
console.log(result);
Regarding a comment i guess i have to explain this a little for those who may not be familiar with some ES6 functionalities.
Object.values() is a Object method which returns all own property values in an array.
So we are reducing our objects into an hash object of which we collect the properties by Object.values() later. While reducing we check if the currently examined object's date value exists as key in our map. If not we create that key and insert the examined object at that key position, if yes then we increment the previously inserted objects amount property by the value of currently examined objects amount value.
If you don't want to mutate the original data then please change r[d.date] = d into r[d.date] = Object.assign({},d).
The way I would do it is to create an object with the dates as the key, then you can iterate over the array and create a new date property if it doesn't exist or increase the amount if it does, then convert it back into an array:
const items = data.reduce((acc, curr) => {
if (!acc[curr.date]) { // basically creating a property with the date as the key and the value is the current object
acc[curr.date] = { ...curr };
} else { // if it exists already, then just increment the amount
acc[curr.date].amount += curr.amount;
}
return acc;
}, {});
const newArray = Object.values(items); // grab all the values from the object above
I have an array of object and I want to count the number of distinct elements and counts of those objects.
[ { name: 'Suman',
game: '5A'
},
{ name: 'Suman',
game: '5A'
},
{ name: 'Namus',
game: '5A'
},
{ name: 'Namus',
game: '5A'
}
]
I want to count the number of distinct names and store them in an object. I have tried it by 1# pushing all the names in an array,
2# then sorting them,
3# then calculating the number of distinct names and
4# finally pushing them to the object.
This process is too long. Is there a shorter way to do this. I am using Nodejs
Thanks in advance
You will create a new object, where the key is the name and the value the count:
var youArr = [
{ name: 'Suman',
game: '5A'
},
{ name: 'Suman',
game: '5A'
},
{ name: 'Namus',
game: '5A'
},
{ name: 'Namus',
game: '5A'
}
];
var count = {}
for(var i=0; i < youArr.length; i++){
count[youArr[i].name] = count[youArr[i].name] || 0;
count[youArr[i].name]++;
}
alert(count['Namus']); // 2
This is a great place to use the reduce function:
The reduce() method applies a function against an accumulator and each
value of the array (from left-to-right) has to reduce it to a single
value.
...
reduce executes the callback function once for each element present in
the array, excluding holes in the array, receiving four arguments: the
initial value (or value from the previous callback call), the value of
the current element, the current index, and the array over which
iteration is occurring.
It would look something like this:
var arr = [ { name: 'Suman',
game: '5A'
},
{ name: 'Suman',
game: '5A'
},
{ name: 'Namus',
game: '5A'
},
{ name: 'Namus',
game: '5A'
}
]
var counts = arr.reduce(function(counts, item) {
counts[item.name] = (counts[item.name] || 0) + 1;
return counts;
}, {});
counts is then:
{ Suman: 2, Namus: 2 }
Asked in the comments:
what if i want the count as well as name in an array of object like
[{name: 'Suman', count:'2'}, {name:'Namus', count:'2'}]
If you already have counts from the reduce call above, then you can map its keys to the format you want:
var countsArray = Object.keys(counts).map(function(name) {
return {name: name, count: counts[name]};
});
countsArray is then:
[ { name: 'Suman', count: 2 },
{ name: 'Namus', count: 2 } ]