AngularJS array split - javascript

I am relatively new to AngularJS. I am getting my data from java spring through $http.get request in the following format:
[
{
"obj1": 1039751,
"obj2": "ABC",
"obj3": "INDIA",
"obj4": 57,
"obj5": 16,
"obj6": 43
},
{
"obj1": 895321,
"obj2": "PQR",
"obj3": "AUSTRALIA",
"obj4": 86,
"obj5": 43,
"obj6": 24
},
{
"obj1": 926384,
"obj2": "MNO",
"obj3": "DUBAI",
"obj4": 16,
"obj5": 12,
"obj6": 76
},
{
"obj1": 837537,
"obj2": "LMN",
"obj3": "ENGLAND",
"obj4": 83,
"obj5": 15,
"obj6": 43
},
{
"obj1": 867152,
"obj2": "JKL",
"obj3": "JAPAN",
"obj4": 49,
"obj5": 76,
"obj6": 16
},
{
"obj1": 1003783,
"obj2": "XYZ",
"obj3": "BHUTAN",
"obj4": 16,
"obj5": 42,
"obj6": 94
},
{
"obj1": 864287,
"obj2": "DEF",
"obj3": "USA",
"obj4": 96,
"obj5": 16,
"obj6": 37
}
]
My app.js:
var app = angular.module("myApp", ['smart-table']);
app.controller("ctrl", function($scope, $rootScope, $timeout, $http) {
init();
function init() {
$scope.rowCollection = {};
$scope.isGlobalVisible = {};
$http.get('rest/obz/getAllObjects').success(function(obdata) {
console.log(obdata);
$scope.rowCollection = obdata;
console.log(rowCollection);
}).error(function() {
console.log("Error");
});
}
});
I want to split the above array as separate arrays of obj1, obj2, obj3, obj4, obj5 and obj6 in AngularJS.as
obj1 = [{1039751,895321,926384,837537,867152,1003783,864287}]
obj2 = [{"ABC","PQR","MNO","LMN","JKL","XYZ","DEF"}]
and so on.
How to split them separably in js?

Have you tried angular.forEach and push the values on the new objects?
Something like
$http.get('rest/obz/getAllObjects')
.success(function(obdata){
console.log(obdata);
$scope.rowCollection = obdata;
console.log(rowCollection);
angular.forEach($scope.rowCollection, function(value, key) {
if (this[key] == undefined) {
this[key] = [];
};
this[key].push(value);
});
}).error(function(){
console.log("Error");
});

Related

How do I use reduce to create array of objects with repeating keys

I have an array of objects that looks like this:
const data = [
{
"date": "2020-01-02",
"run": [
{"time": "1", "result": 100},
{"time": "2", "result": 150},
{"time": "3", "result": 92}
]
},
{
"date": "2020-01-15",
"run": [
{"time": "1", "result": 90},
{"time": "2", "result": 86},
{"time": "3", "result": 133}
]
},
{
"date": "2020-02-11",
"run": [
{"time": "1", "result": 45},
{"time": "2", "result": 176},
{"time": "3", "result": 108}
]
},
]
I'd like it to look like this:
[
{
"time": 1,
"2020-01-02": 100,
"2020-01-15": 90,
"2020-02-11": 45
},
{
"time": 2,
"2020-01-02": 150,
"2020-01-15": 86,
"2020-02-11": 176
},
{
"time": 3,
"2020-01-02": 92,
"2020-01-15": 133,
"2020-02-11": 108
},
]
I've tried using reduce like this:
const initVal = {
[data[0].date]: data[0].run[0].result
};
const newArr = data.reduce((prev, curr, currIdx) => {
return {
...prev, ...initVal, [curr.date]: curr.run[currIdx-1].result
}
});
but getting this:
{
"2020-01-02": 100,
"2020-01-15": 90,
"2020-02-11": 176,
date: "2020-01-02"
run:[{…}, {…}, {…}]
}
So not quite there yet. I know I need it to iterate over each of the "run" arrays to get all the correct values for each "time" -- how do I set up what's missing?
You can preprocess your array to make it easier for reduce, for example, convert it to the list of pairs [key, payload]:
data
.flatMap(d =>
d.run.map(r => [r.time, {[d.date]: r.result}]))
This produces:
[
[ '1', { '2020-01-02': 100 } ],
[ '2', { '2020-01-02': 150 } ],
[ '3', { '2020-01-02': 92 } ],
[ '1', { '2020-01-15': 90 } ], etc
Now we can group things together:
.reduce((m, [key, payload]) =>
m.set(key, Object.assign({}, m.get(key), payload)),
new Map)
which creates the following Map:
Map(3) {
'1' => { '2020-01-02': 100, '2020-01-15': 90, '2020-02-11': 45 },
'2' => { '2020-01-02': 150, '2020-01-15': 86, '2020-02-11': 176 },
'3' => { '2020-01-02': 92, '2020-01-15': 133, '2020-02-11': 108 }
}
The rest should be easy, good luck!
You could use an object for grouping and get the values as result.
const
data = [{ date: "2020-01-02", run: [{ time: "1", result: 100 }, { time: "2", result: 150 }, { time: "3", result: 92 }] }, { date: "2020-01-15", run: [{ time: "1", result: 90 }, { time: "2", result: 86 }, { time: "3", result: 133 }] }, { date: "2020-02-11", run: [{ time: "1", result: 45 }, { time: "2", result: 176 }, { time: "3", result: 108 }] }],
result = Object.values(data.reduce((r, { date, run }) => {
run.forEach(({ time, result }) => {
r[time] ??= { time };
r[time][date] = result;
});
return r;
}, {}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

How to map and group array of objects

I'm building an application with Node.js, Express, Postgres and Sequelize.
I get a response that looks like this:
[
{
"id": 101,
"type": 0,
"bookings": [
{
"date": "2019-04-15T02:00:00.000Z"
}
]
},
{
"id": 102,
"type": 4,
"bookings": [
{
"date": "2019-04-17T02:00:00.000Z"
}
]
},
{
"id": 103,
"type": 0,
"bookings": [
{
"date": "2019-04-15T02:00:00.000Z"
}
]
},
{
"id": 104,
"type": 0,
"bookings": [
{
"date": "2019-04-17T02:00:00.000Z"
}
]
}
]
I want to group all the events that happen on the same date.
I tried
_.forEach(response, function(value) {
_.groupBy(value, value.bookings[0].date)
})
but it doesn't work.
How can I map and group an array?
Eventually I want to have an object (or array) that looks something like this:
{
2019-04-15: [
{ id: 101, type: 0 }, { id: 103, type: 0}
],
2019-04-17: [
{ id: 102, type: 4 }, { id: 104, type: 0}
]
}
You can use reduce
let data = [{"id": 101,"type": 0,"bookings": [{"date": "2019-04-15T02:00:00.000Z"}]},{"id": 102,"type": 4,"bookings": [{"date": "2019-04-17T02:00:00.000Z"}]},{"id": 103,"type": 0,"bookings": [{"date": "2019-04-15T02:00:00.000Z"}]},{"id": 104,"type": 0,"bookings": [{"date": "2019-04-17T02:00:00.000Z"}]}]
let op = data.reduce((op,{bookings,...rest}) => {
let key = bookings[0].date.split('T',1)[0]
op[key] = op[key] || []
op[key].push(rest)
return op
},{})
console.log(op)
You can use the function reduce for grouping the objects by date.
This is assuming the array has only one index.
let arr = [ { "id": 101, "type": 0, "bookings": [ { "date": "2019-04-15T02:00:00.000Z" } ] }, { "id": 102, "type": 4, "bookings": [ { "date": "2019-04-17T02:00:00.000Z" } ] }, { "id": 103, "type": 0, "bookings": [ { "date": "2019-04-15T02:00:00.000Z" } ] }, { "id": 104, "type": 0, "bookings": [ { "date": "2019-04-17T02:00:00.000Z" } ] }];
let result = arr.reduce((a, {id, type, bookings: [{date}]}) => {
let key = date.substring(0, 10);
(a[key] || (a[key] = [])).push({id, type});
return a;
}, Object.create(null));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can also use this to accomplish what you're looking for.
let response = [
{
"id": 101,
"type": 0,
"bookings": [
{
"date": "2019-04-15T02:00:00.000Z"
}
]
},
{
"id": 102,
"type": 4,
"bookings": [
{
"date": "2019-04-17T02:00:00.000Z"
}
]
},
{
"id": 103,
"type": 0,
"bookings": [
{
"date": "2019-04-15T02:00:00.000Z"
}
]
},
{
"id": 104,
"type": 0,
"bookings": [
{
"date": "2019-04-17T02:00:00.000Z"
}
]
}
]
let dateGroupings = {};
response.forEach((v)=> {
let date = v.bookings[0].date.substring(0,10)
if (!dateGroupings[date]){
dateGroupings[date] = [];
}
let obj = {
id: v.id,
type: v.type
};
dateGroupings[date].push(obj);
})
Well i didn't see that many answers but since i did it too
const data = [
{
"id": 101,
"type": 0,
"bookings": [
{
"date": "2019-04-15T02:00:00.000Z"
}
]
},
{
"id": 102,
"type": 4,
"bookings": [
{
"date": "2019-04-17T02:00:00.000Z"
}
]
},
{
"id": 103,
"type": 0,
"bookings": [
{
"date": "2019-04-15T02:00:00.000Z"
}
]
},
{
"id": 104,
"type": 0,
"bookings": [
{
"date": "2019-04-17T02:00:00.000Z"
}
]
}
];
const bookingsByDate = {};
data.forEach((booking) => {
booking.bookings.forEach((bookingDate) => {
const date = new Date(bookingDate.date);
const day = date.getDate() < 10 ? '0' + date.getDate(): date.getDate();
const month = date.getMonth() < 10 ? '0' + date.getMonth(): date.getMonth();
const year = date.getFullYear();
const fullDate = year + '-' + month + '-' + day;
if(!bookingsByDate[fullDate]) {
bookingsByDate[fullDate] = [];
}
bookingsByDate[fullDate] = [
...bookingsByDate[fullDate],
{
id: booking.id,
type: booking.type,
}
]
});
})
console.log(bookingsByDate);

Fetch the no of of occurence in a array based on other key value

var json = [{
"city": "California",
"name": "Joe",
"age": 17,
"type",:"custom"
}, {
"city": "California",
"name": "Bob",
"age": 17,
"type",:"predefined"
}, {
"city": "California",
"name": "Bob",
"age": 35,
"type",:"custom"
}, {
"city": "Texas",
"name": "Bob",
"age": 35,
"type",:"custom"
}, {
"city": "Florida",
"name": "Bob",
"age": 35,
"type",:"predefined"
}];
I have above array and i have to construct object, based on "type" value i.e "predefined" or "custom" as below
updatedjson = {
"predefined": [{
"name": "California",
"count": 1
}, {
"name": "Florida",
"count": 1
}]
"custom": [{
"name": "California",
"count": 2
}, {
"name": "Texas",
"count": 1
}]
}
Any Approach using javascript or lodash
Using Lodash
var json = [{
"city": "California",
"name": "Joe",
"age": 17,
"type": "custom"
}, {
"city": "California",
"name": "Bob",
"age": 17,
"type": "predefined"
}, {
"city": "California",
"name": "Bob",
"age": 35,
"type": "custom"
}, {
"city": "Texas",
"name": "Bob",
"age": 35,
"type": "custom"
}, {
"city": "Florida",
"name": "Bob",
"age": 35,
"type": "predefined"
}];
// Solution to the problem
var updatedJson = _(json).groupBy("type").value(); // #1
_.forOwn(updatedJson, function(value, key) {
let countByCity = _(value).countBy('city').value(); // #2
let res = [];
_.forOwn(countByCity, function(value, key) {
res.push({ // #3
name: key,
count: value
});
});
updatedJson[key] = res;
});
console.log(updatedJson);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
Explanation
Code first groups by type
Then counts by cities, within the group
Finally pushes the count object into an array, in the expected format
You can use reduce & findIndex
var json = [{
"city": "California",
"name": "Joe",
"age": 17,
"type": "custom"
}, {
"city": "California",
"name": "Bob",
"age": 17,
"type": "predefined"
}, {
"city": "California",
"name": "Bob",
"age": 35,
"type": "custom"
}, {
"city": "Texas",
"name": "Bob",
"age": 35,
"type": "custom"
}, {
"city": "Florida",
"name": "Bob",
"age": 35,
"type": "predefined"
}];
var updatedjson = json.reduce(function(result, item) {
// check if type is present in the object
// if not present then add a key by name custom/predefined
if (!result[item.type]) {
result[item.type] = [];
// add city name and intial count
result[item.type].push({
name: item.city,
count: 1
})
} else {
// now find the index of the object whe name matches with current city
let m = result[item.type].findIndex(function(obj) {
return obj.name === item.city
})
// if no matches then add the new object to either custom/predefined
if (m === -1) {
result[item.type].push({
name: item.city,
count: 1
})
} else {
// if matches then increase the value of count
result[item.type][m].count += 1
}
}
return result;
}, {});
console.log(updatedjson)
You can use array.reduce to create a new object with the aggregated data. Example:
const result = json.reduce((obj, data) => {
// if this is a new type, we must initialize it as an empty array and push the first record.
if(!obj[data.type]) {
obj[data.type] = [];
obj[data.type].push({name: data.city, count: 1});
return obj;
}
// else ... check if the current city is present in that type
const existingRecord = obj[data.type].find(d => d.name === data.city);
if(!existingRecord) {
// if the city is not present in that type, we initialize it with count 1
obj[data.type].push({name: data.city, count: 1});
return obj;
}
// if the city is present, we just update count = count + 1;
existingRecord.count++;
return obj;
}, { })
Now, you probably want to extract some of that logic into separate functions to increase readability. I don't think you need lodash for this but in the case you already have it included in your project then feel free to use it :P

How can I pull out two elements of every object in an array of objects and make a new one

I have an array whose length could be > 1 at any time and just keep getting bigger.
I need to extract only TWO of the values of the parent array elements and put them into a new array.
Here's the example of the base array:
{
"strains":[
{
"id": 150,
"name": "Animal Cookies (Phat Panda)",
"label": "Animal Cookies (Phat Panda)",
"thcpct": 14,
"cbdpct": 19,
"ttlpct": 33,
"type": "Hybrid SD",
"subtype": "Sativa Dominant",
"bitactive": 1,
"useradded": "jjones",
"dateadded": "4/12/2017"
},
{
"id": 110,
"name": "Blue Dream (Pioneer)",
"label": "Blue Dream (Pioneer)",
"thcpct": 24,
"cbdpct": 0,
"ttlpct": 24,
"type": "Sativa",
"subtype": "None",
"bitactive": 1,
"useradded": "jjones",
"dateadded": "3/27/2017"
},
{
"id": 30,
"name": "Candyland",
"label": "Candyland",
"thcpct": 25,
"cbdpct": 75,
"ttlpct": 100,
"type": "Hybrid SD",
"subtype": "Sativa Dominant",
"bitactive": 1,
"useradded": "jjones",
"dateadded": "1/1/2017"
},
{
"id": 130,
"name": "Dragon OG (Avitas)",
"label": "Dragon OG (Avitas)",
"thcpct": 26,
"cbdpct": 18,
"ttlpct": 44,
"type": "Hybrid SD",
"subtype": "Sativa Dominant",
"bitactive": 1,
"useradded": "jjones",
"dateadded": "4/10/2017"
}
]
}
and this is what I want it to look like after the extraction:
{
"strains":[
{
"id": 150,
"label": "Animal Cookies (Phat Panda)",
},
{
"id": 110,
"label": "Blue Dream (Pioneer)",
},
{
"id": 30,
"label": "Candyland",
},
{
"id": 130,
"label": "Dragon OG (Avitas)",
}
]
}
The way I've tried to do this is with push, one array equals another and still I get Push is NOT a function, or 'id' is undefined and the code stops.
This is EASY STUFF and assigning one array element to another is not difficult but why is this case so different?
I have the example code for what I've tried here:
I've tried using LODASH here:
//This is the call to the FIX_KEY function in appservice
_.object(
_.map(
_.keys(allStrains.data),
ctrlMain.appSvc.appFuncs.fix_key(/^name/, 'label')),
_.values(allStrains.data)
);
Here's the function in appservice:
svc.appFuncs = {
//https://stackoverflow.com/questions/32452014/change-key-name-in-javascript-object
//This replaces a STATIC key value for now, but can probably
//replace any value
fix_key: function (key, keyname) {
return key.replace(key, keyname);
}
}
I modified a lodash code from the Stack Overflow question in the comments.
UPDATE 1:
Andrjez, please see the end result on how I need to make this work and where I'm experiencing the problem:
* Angular Dropdown Multi-select
*
* For STRAINS to select what will be in the room selected
*
*/
$scope.example8model = [];
//Get the data from LOCALSTORAGE
var getResults;
**//I GET THE RESULTS from LOCAL STORAGE HERE**
getResults = storageLocalService.getItemJSON("allstrains");
**//CHECK the strains from LOCAL STORAGE**
console.log("Strains: ", getResults.strains); //FAILS HERE!!!
//getResults.strains is UNDEFINED but getResults HOLDS the JSON
//EXACTLY how you made it in your example. I just changed
//**obj** to **getResults**.
var result = {
//NEXT LINE FAILS: getResults.strains.map is UNDEFINED!
strains: getResults.strains.map(function (item) {
return {
id: item.id,
label: item.label
};
})
};
console.log("All extracted Strains: ", result);
$scope.example8model = result;
//$scope.example8data = [
// {id: 1, label: "David"},
// {id: 2, label: "Jhon"},
// {id: 3, label: "Danny"}
//];
$scope.example8settings = {
checkBoxes: true
};
Here's the problem: The data in LOCAL STORAGE does NOT have double-quotes either leading or trailing. BUT...
This is what I get in the DEV CONSOLE:
Notice, no DBL QUOTE ADDED for leading or trailing:
Then when I click to the NEXT level down, DOUBLE QUOTES ARE ADDED thus messing up trying to access: getResults.strains.map()...
Finally, the resulting Error...
So, where am I going wrong?
NOTE: This is what I'm trying to achieve: MULTI-SELECT
Use Array.prototype.map:
var result = {
strains: obj.strains.map(function (item) {
return {
id: item.id,
label: item.label
};
})
};
Try the snippet below to see the result:
var obj = {
"strains":[
{
"id": 150,
"name": "Animal Cookies (Phat Panda)",
"label": "Animal Cookies (Phat Panda)",
"thcpct": 14,
"cbdpct": 19,
"ttlpct": 33,
"type": "Hybrid SD",
"subtype": "Sativa Dominant",
"bitactive": 1,
"useradded": "jjones",
"dateadded": "4/12/2017"
},
{
"id": 110,
"name": "Blue Dream (Pioneer)",
"label": "Blue Dream (Pioneer)",
"thcpct": 24,
"cbdpct": 0,
"ttlpct": 24,
"type": "Sativa",
"subtype": "None",
"bitactive": 1,
"useradded": "jjones",
"dateadded": "3/27/2017"
},
{
"id": 30,
"name": "Candyland",
"label": "Candyland",
"thcpct": 25,
"cbdpct": 75,
"ttlpct": 100,
"type": "Hybrid SD",
"subtype": "Sativa Dominant",
"bitactive": 1,
"useradded": "jjones",
"dateadded": "1/1/2017"
},
{
"id": 130,
"name": "Dragon OG (Avitas)",
"label": "Dragon OG (Avitas)",
"thcpct": 26,
"cbdpct": 18,
"ttlpct": 44,
"type": "Hybrid SD",
"subtype": "Sativa Dominant",
"bitactive": 1,
"useradded": "jjones",
"dateadded": "4/10/2017"
}
]
};
var result = {
strains: obj.strains.map(function (item) {
return {
id: item.id,
label: item.label
};
})
};
console.log(result);
If you wish to use es6 features:
const result = { strains: obj.strains.map(({id , label}) => ({id, label})) };
obj.strains = obj.strains.map(x => ({ id: x.id, label: x.label }));
If it's more than just strains, and you want to apply the same logic to each sub array:
let filtered = Object.entries(obj)
.filter(([k, arr]) => Array.isArray(arr))
.reduce((acc, [k, arr]) => {
acc[k] = arr.map(x => ({ id: x.id, label: x.label }));
return acc;
}, {});
My Solution:
var test = 'label'
var results = [];
var response = strains.forEach( obj => {
if (obj[test]) {
results = [
...results,
{
test: obj[test]
}
];
}
});
console.log('matches', results);
//output: matches, [{test: "Animal Cookies (Phat Panda)"}, {test: "Blue Dream (Pioneer)"}, {test: "Candyland"}, {test: "Dragon OG (Avitas)"}]
for (n of strains) {
n = n.filter(function(elem,index){
return (index == "id" || index == "label")
});
}
Something like that?

Underscore have some function to extract nested array of objects to new array?

I have:
[{
"id": 1,
"listForExtract": [{
"value1": "1A",
"value2": "2A"
}, {
"value1": "1B",
"value2": "2B"
}, ]
},
{
"id": 2,
"listForExtract": [{
"value1": "1C",
"value2": "2C"
}, {
"value1": "1D",
"value2": "2D"
}, ]
}]
I want to extract the objects inside listForExtract to a new array like using some function of underscore passing the ID:
something like: _.extractNestedArrayFrom(myArray, 'listForExtract', {'id':2})
[{
"value1": "1A",
"value2": "2A"
}, {
"value1": "1B",
"value2": "2B"
}]
You could use where, pluck and flatten:
var result = _.chain(data)
.where({id:2})
.pluck('listForExtract')
.flatten()
.value()
Where finds all the items in the array that have an id of 2 and pluck extracts the listForExtract. Flatten is then used to flatten the result into one array
You don't even need underscore for that.
Following code should work for you.
myArray.filter(function(){
return o.id==2
}).map(function(o){
return o.listForExtract
});
You can combine map and where methods
var myArray = [{
"id": 1,
"listForExtract": [{
"value1": "1A",
"value2": "2A"
}, {
"value1": "1B",
"value2": "2B"
}, ]
},
{
"id": 2,
"listForExtract": [{
"value1": "1C",
"value2": "2C"
}, {
"value1": "1D",
"value2": "2D"
}, ]
}];
var result = _.map(_.where(myArray, {
'id': 2
}), function(elem) {
return elem.listForExtract
});
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>

Categories