I have the following array and three vars:
array1 = ['']
dateOutput = 1/1/14
timeOutput = 12am
tallysave = 100
I was using this to push in the three vars on a push
array1.push(dateOutput + ', ' + timeOutput + tallysave)
However how can I push each of the vars into the array so they will be like this when pushed: (multi-dimensional array?)
array = [
{ "date": dateOutput, "time": timeOutput, },
];
You can push the data as an object:
array1.push({
"date": dateOutput,
"time": timeOutput
});
array1.push({ "date": dateOutput, "time": timeOutput})
or
array1.push([dateOutput, timeOutput])
But in the second way you should know that dateOutput with index 0, and timeOutput with index 1
Related
There is an array of objects
const data = [{
"name": "08/20/2018",
"id": "name_1"
}, {
"name": "12/23/2018",
"id": "name_2"
}]
and I would like to map this array of objects in order to get just array
["Date 1","08/20/2018","Date 2","12/23/2018"]
I'm trying using .map()
data.map((d, i) =>
`${'Date ' + i}`
d.name
)];
but cannot map name with the first (d) parameter.
Because the input items and output array items aren't one-to-one, you won't be able to use .map. Use reduce instead:
const data = [{
"name": "08/20/2018",
"id": "name_1"
}, {
"name": "12/23/2018",
"id": "name_2"
}];
const output = data.reduce((a, { name }, i) => {
a.push('Date ' + (i + 1), name);
return a;
}, []);
console.log(output);
Or .flatMap:
const data = [{
"name": "08/20/2018",
"id": "name_1"
}, {
"name": "12/23/2018",
"id": "name_2"
}];
const output = data.flatMap(({ name }, i) => (['Date ' + (i + 1), name]));
console.log(output);
(note that since arrays are zero-indexed, you'll have to use i + 1, not i, if you want the first item in the output array to start at 1 instead of 0)
You can't use map since that method produce a new array with the same number of items of the original ones.
However, you can use flatMap (where supported) to achieve the your desired result:
data.flatMap(({name}, i) => [`Date ${i + 1}`, name]);
console.log(data) // [ "Date 1", "08/20/2018", "Date 2", "12/23/2018" ]
Basically flatMap is like calling map and then flat; therefore if from the callback function we returns an array per item, this array will be flattened before returned.
Regular map call would have been produced [[ "Date 1", "08/20/2018"], ["Date 2", "12/23/2018"]] instead.
Try to combine map and flatmap methods in order to achieve desired result:
const data = [{
"name": "08/20/2018",
"id": "name_1"
}, {
"name": "12/23/2018",
"id": "name_2"
}];
const result = data.map((s, i)=> [`Date ${i}`, s.name]).flatMap(f=> f);
console.log(result)
or using flat method:
const data = [{
"name": "08/20/2018",
"id": "name_1"
}, {
"name": "12/23/2018",
"id": "name_2"
}];
const result = data.map((s, i)=> [`Date ${i}`, s.name]).flat(1);
console.log(result)
One line answer using ES2019 Array.flat :
data.map((item,index)=>([`Date${index+1}`,item.name])).flat();
But in my opinion, it is not optimized when there is huge data.
I appreciate above answers but if you still prefer to use .map() method to accomplish your work, you can do it.
Just with an additional use of concat() method with map() method. Let's see how.
I have used ...data,map() statement where ... is used for Array destructuring. More information can be found at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Array_destructuring.
const data = [
{
"name": "08/20/2018",
"id": "name_1"
},
{
"name": "12/23/2018",
"id": "name_2"
}
]
output = new Array() // or just []
output = output.concat(...data.map((obj, index) => [`Date ${index + 1}`, obj.name]))
console.log(output)
// [ 'Date 1', '08/20/2018', 'Date 2', '12/23/2018' ]
Screenshot
I am trying to get the count from JSON response which has current date in the key.
Json Response:
[
{
"type": {
"id": "mobile",
"name": "mobile",
"description": "",
"total_count": 0
},
"counts": [
{
"date": "2018-09-06",
"timestamp": 1536192000000,
"count": 20
},
{
"date": "2018-09-07",
"timestamp": 1536278400000,
"count": 10
}
]
},
{
"type": {
"id": "lap",
"name": "lap",
"description": "",
"total_count": 0
},
"counts": [
{
"date": "2018-09-06",
"timestamp": 1536192000000,
"count": 19
},
{
"date": "2018-09-07",
"timestamp": 1536278400000,
"count": 20
}
]
}
]
My New try as per vikscool code:
var json_count = JSON.parse(getcounts);
var curDate = getCurrentDate();
var mobilcount = () => json_count.map(ct => {
const count = ct.counts;
const getDate = count.find(dt => dt.date === curDate);
window.alert('count is ', getDate.count);
return {getDate};
});
mobilcount();
function getCurrentDate () {
var nowDate = new Date();
var month = (nowDate.getMonth() + 1).toString().length == 1
? '0' + (nowDate.getMonth() + 1)
: (nowDate.getMonth() + 1);
var day = nowDate.getDate().toString().length == 1
? '0' + nowDate.getDate()
: +nowDate.getDate();
return nowDate.getFullYear() + '-' + month + '-' + day;
}
output: "count is "
but there is no count printed from json.
Is there any solution in Javascript I can get the current date and get the counts.
I need to get the count as 10 in mobilcount.
As the dates are stored in the JSON Array key named as the counts of the first object of the json_count you can not fetch it using:
var instance_count=json_count[0].values[2].count;
As your json object does not have any key named as values.
What you have to do is first access the counts key then get the particular object from it which contains the particular(current date as in your case) and then get the counts from it.
Below is a sample code to get the particular date's count:
//assuming this is the Json response you are getting as complete JSON response is not provided by the OP.
var getcounts = `[{"type":{"id":"mobile","name":"mobile","description":"","total_count":0},"counts":[{"date":"2018-09-05","timestamp":1533686400000,"count":0},{"date":"2018-09-06","timestamp":1533772800000,"count":8}]}]`;
//parsing the given json String
var json_count = JSON.parse(getcounts);
function getCountForCurrentDate() {
var curDate = getCurrentDate(); //for which the data is to be fetched and making in format of the dates in JSON as yyyy-mm-dd
//finding the particular object that contains the current date
var searchedObj = json_count[0]['counts'].find(f => f['date'] == curDate);
if(searchedObj!==undefined)
console.log('count is', searchedObj['count']);
}
function getCurrentDate() {
var nowDate = new Date();
var month = (nowDate.getMonth() + 1).toString().length == 1 ? '0' + (nowDate.getMonth() + 1) : (nowDate.getMonth() + 1);
var day = nowDate.getDate().toString().length == 1 ? '0' + nowDate.getDate() : +nowDate.getDate();
return nowDate.getFullYear() + '-' + month + '-' + day;
}
getCountForCurrentDate();
Here in the snippet above, i have created two functions getCurrentDate() to get the current date in the format it is stored in JSON response and getCountForCurrentDate() to get the count from the json_count variable.
Update 1 as per the new requirement is given by OP
The given JSON object is as follows:
var json_count = [
{
type: {
id: "mobile",
name: "mobile",
description: "",
total_count: 0
},
counts: [
{
date: "2018-09-06",
timestamp: 1536192000000,
count: 20
},
{
date: "2018-09-07",
timestamp: 1536278400000,
count: 10
}
]
},
{
type: {
id: "lap",
name: "lap",
description: "",
total_count: 0
},
counts: [
{
date: "2018-09-06",
timestamp: 1536192000000,
count: 19
},
{
date: "2018-09-07",
timestamp: 1536278400000,
count: 20
}
]
}
];
And now as the object has two entities one for mobile and another for lap we can fetch the particular values as:
var mobile = json_count.find(f=>f['type']['id']=='mobile');//comparing the value present in the json object at location type.id to 'mobile' (change it to 'lap' or anything that is present in the id of the object).
and now to get the count for it we do as:
var mobile_count = mobile.counts.find(f=>f['date']=='2018-09-07');//replace the static date with the date you want to fetch the count from
and then access the count as:
console.log(mobile_count.count);
//output:10
I am new to Lodash and Functional Programming concepts. So, I have an array of objects with day-wise date like these:
[
{
"date": '1-Jan-2015',
"count": 4
},
{
"date": '4-Jan-2015',
"count": 3
},
{
"date": '1-Feb-2015',
"count": 4
},
{
"date": '18-Feb-2015',
"count": 10
}
]
and I want to reduce and aggregate it in such a way that I get an array of objects where each object has monthly data instead of day-wise data like this:
[
{
"date": 'Jan, 2015',
"count": 7 // aggregating the count of January
},
{
"date": 'Feb, 2015',
"count": 14 //aggregating the count of February
}
]
Currently, I have a written a very unreadable and convoluted code full of ifs and fors which works. However, I want to refactor it using lodash. Is it possible using lodash? I looked around and found _.reduce and _.groupBy which I can probably use but I am stumped right now and can't figure out a good clean implementation.
We can use _.reduce & _.values
var arr = [
{
"date": '1-Jan-2015',
"count": 4
},
{
"date": '4-Jan-2015',
"count": 3
},
{
"date": '1-Feb-2015',
"count": 4
},
{
"date": '18-Feb-2015',
"count": 10
}
]
_.values(_.reduce(arr,function(result,obj){
var name = obj.date.split('-');
name = name[1]+', '+name[2];
result[name] = {
date:name,
count:obj.count + (result[name]?result[name].count:0)
};
return result;
},{}));
You don't need lodash to achieve what you want, you could use plain old Javascript:
var array = [{
"date": '1-Jan-2015',
"count": 4
}, {
"date": '4-Jan-2015',
"count": 3
}, {
"date": '1-Feb-2015',
"count": 4
}, {
"date": '18-Feb-2015',
"count": 10
}]
var result = array.reduce(function(ar, item) {
var index = item.date.split('-').slice(1,3).join(', ') //getting date Month-Year
_item = ar.filter(function(a) {
return a.date === index
})[0] // getting item if already present in array
// getting index of _item if _item is already present in ar
indexOf = ar.indexOf(_item)
if(indexOf > -1)
// we sum the count of existing _item
ar[indexOf] = {date: index, count: count: _item.count + item.count }
else
// item is not yet in the array, we push a new _item
ar.push({date: index, count: item.count})
return ar; // return the array as required by reduce
}, []) // initialize the reduce method with an empty array
console.log(result) // your array with aggregated dates
And for the fun, a lodash version:
_.values(array.reduce(function(obj, item) {
var index = item.date.split('-').slice(1, 3).join(', ')
obj[index] = {date: index, count: (obj[index] && obj[index].count || 0) + item.count}
return obj
}, {}))
See jsfiddle here
I am receiving real-time responses from the back-end that contains the following JSON (almost every second):
One Array:
{
"newUpdate": [
{
"id": "TP",
"val" : 3
},
{
"id": "TPE20",
"val" : 3
}]
}
Another array (after one second or less)
{
"newUpdate": [
{
"id": "CRK",
"val" : 24
},
{
"id": "TPE20",
"val" : 44
}]
}
I am getting the above JSON almost every second knowing that each time it comes with different values and id's, and the array itself does not have a specific size.
Well, what I want to do is to get the average of the values having the same key 'id'.
For example, for the above array, the average will be for TPE20 :
(3+44)/2 =23.2 (as it computes the average for the id : TPE20)
Then it should show it here (using JQuery for example) [Think of the real-time average value like in the stock market]
<div id="TPE20"></div>
Currently, using the below for loop, I print the JSON listed above:
for(var i in load.updates){
var id = load.newUpdate[i].id;
updatesMap[id] = load.newUpdate[i].value;
var valueOfID = newUpdate[id];
}
The challenge is that I am receiving a lot of arrays at once (1/sec), each array contains different "id" and "val", I really don't know how I can compute the average using the way I described above!
Just use an object with keys representing the ids of the array objects and the values as objects containing the count, total, and average of those ids.
When you receive a new array simply update the object:
function updateObj(arr) {
arr.forEach(function(el) {
var key = el.id;
obj[key] = obj[key] || { count: 0, total: 0, avg: 0 };
obj[key].count++;
obj[key].total += el.val;
obj[key].avg = obj[key].total / obj[key].count;
});
}
Here's a simulation with setInterval sending one array to the function each second, and then displaying the completed object in the console.
Does this help? It get the Average of the search term like you asked. It uses jquery $.each to iterate through the array
var newdata = [
{
"newUpdate": [
{
"id": "TP",
"val" : 3
},
{
"id": "TPE20",
"val" : 3
}]
},
{
"newUpdate": [
{
"id": "CRK",
"val" : 24
},
{
"id": "TPE20",
"val" : 44
}]
}
]
function getAverage(array, term){
var sum = 0, n = 0;
$.each(array, function(i, item){
n++
var arrs = item.newUpdate
$.each(arrs, function(d, place){
// console.log(d)
if (place.id == term){
sum +=place.val
}
})
})
return sum / n
}
document.write(getAverage(newdata, "TPE20"))
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
You can use Array.prototype.forEach() , create a private property at an object to store number of occasions unique property occurs within callback; pass each object individually to function in succession to maintain averages of properties at single object
var a = {
"newUpdate": [{
"id": "TP",
"val": 3
}, {
"id": "TPE20",
"val": 3
}]
};
var b = {
"newUpdate": [{
"id": "CRK",
"val": 24
}, {
"id": "TPE20",
"val": 44
}]
}
var avg = {};
function update(update) {
update.newUpdate.forEach(function(value, index) {
if (!avg[value.id] || !avg.hasOwnProperty(value.id)) {
avg["_" + value.id] = 1;
avg[value.id] = value.val / avg["_" + value.id];
} else {
++avg["_" + value.id];
avg[value.id] += value.val;
avg[value.id] = avg[value.id] / avg["_" + value.id];
}
});
return avg
}
console.log(update(a), update(b), avg)
I've been trying to do this for an hour now and I can't figure it out.
I have this:
data = [
{
"_id": {
"cid": "gbrzjauzju",
"source": "iwowrzlocc"
},
"revenue": 0,
"leads": 484,
"count": 25400
},
{
"_id": {
"cid": "lewyhgnnhz",
"source": "iwowrzlocc"
},
"revenue": 0,
"leads": 166,
"count": 9821
},
]
I am passing in filters as variable filters with ['cid', 'source'] so I can access it as filters[0] filters[1]
What I am trying to do this is:
arr = {}
for item in data
arrdata =
revenue: item.revenue
leads: item.leads
clicks: item.count
arr['results'][item._id.filters[0]][item._id.filters[1]] = arrdata
I want to set the value of cid and source as the key names as the key name so it would be like this:
results =
iwowrzlocc =
lewyhgnnhz =
revenue: 0
leads: 166
clicks: 9821
gbrzjauzju =
revenue: 0
leads: 484
clicks: 25400
How exactly would I accomplish this? Thank you in advance!
Have you tried to not use the "dot syntax" in item._id.filters[0]?
If I were you, I'd try to split the last statement:
var arr = {};
var item_results = {};
var item_cid = {};
for (i in data) {
var item = data[i];
var array_data = {
revenue: item.revenue,
leads: item.leads,
count: item.count
};
item_cid[item._id[filters[1]]] = array_data;
item_results[item._id[filters[0]]] = item_cid;
};
arr['results'] = item_results;
Just to make things more readable and easier to identify possible problems in your code. I hope I could help you in some way! :)