Compare Multiple JSON Arrays - javascript

I have 3 arrays as displayed below. I have no control over the arrays.
groups_array = [ {
"group" : "Mobile Test Region",
"id" : "251"
}, {
"group" : "Mobile Demo Region",
"id" : "252"
} ]
locations_array = [ {
"location" : "M Testing",
"id" : "1376"
}, {
"location" : "Trade Show Machine",
"id" : "1403"
}, {
"location" : "M Trailer",
"id" : "1471"
}, {
"location" : "Test Los Angeles",
"id" : "1475"
} ]
pairs_array = [ {
"location_id" : "1376",
"group_id" : "251"
}, {
"location_id" : "1475",
"group_id" : "251"
}, {
"location_id" : "1403",
"group_id" : "252"
}, {
"location_id" : "1471",
"group_id" : "252"
} ]
Here is the code I used to loop through the pairs_array and retrieve the location_id's that correspond with the group id. Ti.API.info(pairs_array[s].location_id); outputs 2 location ID's based on the groupid given using e.rowData.groupid.
for (var s = 0; s < pairs_array.length; s++) {
if (e.rowData.groupid === pairs_array[s].group_id) {
Ti.API.info(pairs_array[s].location_id);
}
}
I am trying to compare the strings and retrieve the location names using the location_id's ive gotten from the IF statement. Should I just push the results into an array and loop through the location_array and the results and compare? If so, I'd like to see a good code snippet for that since the few times I tried I was not getting the expected output.

for (var s = 0; s < pairs_array.length; s++) {
if (e.rowData.groupid === pairs_array[s].group_id) {
Ti.API.info(pairs_array[s].location_id);
// find location name
for(var t = 0; t < locations_array.length; t++)
{
if(locations_array[t].id == pairs_array[s].location_id)
{
location_name = locations_array[t].location;
}
}
}
}

Related

How to return the given input values not available in array using mongodb query

I am having one input arrays,EX: let UPID = ["0","1","10"]. i have to check members.regularStudent whether given input values available or not ?, suppose not available means i have to push one array and return the results
My documents:
{
"_id" : "5bb20d7556db6915846da67f",
"members" : {
"regularStudent" : [
"3",
"4"
]
}
},
{
"_id" : "5bb20d7556db6915846da55f",
"members" : {
"regularStudent" : [
"1",
"2"
]
}
}
My Expected Output
[
"0",
"10"
]
My Code:
let UPID = ["0","1","10"]
db.Groups.find(
/*{
"members.regularStudent": { $nin: UPIDs }
}*/
)
.forEach(function(objects){
print(objects)
})
I had updated mycode, kindly see top on my question section, print(objects) means i am having the my objects, based on this variable can you update your answer,
** print(objects) **
{
"_id" : "5bb20d7556db6915846da67f",
"members" : {
"regularStudent" : [
"3",
"4"
]
}
},
{
"_id" : "5bb20d7556db6915846da55f",
"members" : {
"regularStudent" : [
"1",
"2"
]
}
}
You could use map method in combination with filter.
let UPID = ["0","1","10"];
let docs = [{ "_id" : "5bb20d7556db6915846da67f", "members" : { "regularStudent" : [ "3", "4" ] } },
{ "_id" : "5bb20d7556db6915846da55f", "members" : { "regularStudent" : [ "1", "2" ] } }]
let ids = [].concat(...docs.map(elem => elem.members.regularStudent));
console.log(UPID.filter(id => !ids.includes(id)));
Here I use forEach to iterate through the data to get all of the regularStudent data into one array then use filter to filter out the data from UPID array.
const UPID = ["0", "1" , "10"]
let data = [
{
"_id" : "5bb20d7556db6915846da67f",
"members" : {
"regularStudent" : [
"3",
"4"
]
}
},
{
"_id" : "5bb20d7556db6915846da55f",
"members" : {
"regularStudent" : [
"1",
"2"
]
}
}
]
let resularStudents = []
data.forEach(d => {
d.members.regularStudent.forEach(rs => {
resularStudents.push(rs)
})
})
var result = UPID.filter(
function(d) {
return this.indexOf(d) < 0;
},
resularStudents
);
console.log(result);

group array of objects by property first letter

im struggling a little with this, been a while since ive coded javascript ... trying to convert this
items = {
"data": [
{
"name" : "john"
},
{
"name" : "james"
},
{
"name" : "joe"
},
{
"name" : "brian"
},
{
"name" : "bojan"
},
{
"name" : "billy"
},
{
"name" : "dean"
},
{
"name" : "darren"
},
{
"name" : "doug"
}
]
}
into this format
items = {
"data": [
{
letter: "j"
names : ["john", "james", "joe"]
},
{
letter: "b"
names : ["brian", "bojan", "billy"]
},
{
letter: "j"
names : ["dean", "darren", "doug"]
},
]
}
I've been trying to do this using reduce but not having much look.... is there a simpler way to to do it?
You can use reduce to create an object with the letters as keys from which you can extrapolate the array of objects you need by iterating over the object entries using map.
const items = {"data":[{"name":"john"},{"name":"james"},{"name":"joe"},{"name":"brian"},{"name":"bojan"},{"name":"billy"},{"name":"dean"},{"name":"darren"},{"name":"doug"}]};
// `reduce` over the data to produce an object
// with letter keys, and array values where the names are added
const obj = items.data.reduce((acc, c) => {
const letter = c.name[0];
acc[letter] = (acc[letter] || []).concat(c.name);
return acc;
}, {})
// `map` over the object entries to return an array of objects
items.data = Object.entries(obj).map(([letter, names]) => {
return { letter, names }
}).sort((a, b) => a.letter > b.letter);
console.log(items);
Vanilla javascript implementation:
const items = {
"data": [
{
"name" : "john"
},
{
"name" : "james"
},
{
"name" : "joe"
},
{
"name" : "brian"
},
{
"name" : "bojan"
},
{
"name" : "billy"
},
{
"name" : "dean"
},
{
"name" : "darren"
},
{
"name" : "doug"
}
]
}
const transformed = {
data:[]
}
const findByLetter = (letter) => (element) => element.letter === letter;
for(let i = 0; i < items.data.length; i++){
const letter = items.data[i].name.split("")[0];
const elIndex = transformed.data.findIndex(findByLetter(letter));
if(elIndex > -1){
transformed.data[elIndex].names.push(items.data[i].name);
}else{
transformed.data.push({
letter,
names: [items.data[i].name],
});
}
};
console.log(transformed);
Use one reduce():
const items = {"data":[{"name":"john"},{"name":"james"},{"name":"joe"},{"name":"brian"},{"name":"bojan"},{"name":"billy"},{"name":"dean"},{"name":"darren"},{"name":"doug"}]};
let res = items.data.reduce((acc, item) => {
let l = item.name[0];
if (acc.data.filter(e => e.letter == l)[0] === undefined) acc.data.push({'letter': l, names: [] });
acc.data.filter(e => e.letter == l)[0].names.push(item.name);
return acc;
}, {"data": []})
console.log(res)

AngularJS sorting q.all array of objects from service is not working

i have seen many posts on this but for some reason I continue to run into a problem. I am returning multiple promises with $q.all. Each returned promise (from different vendors) is returning identically formatted arrays of objects. After everything is returned and everything is then processed into a single array of objects and then I need to sort the array of objects based on one of three SORT values : (vendor, price, price_estimate)
But when its returned to my controller nothing is sorted.
Sample Object:
{
"vendor" : "Aaa Company",
"product" : "This prod",
"description" : "this cool prod",
"price" : 27.50,
"price_estimate" : 23.25,
"category" : "tool",
...
}
.factory('Products', function($http,$q,promise1,promise2,promise3,promise4,promise5) {
var prods = [] ;
function sortProds(key) {
prods.sort(function(a,b) {
if (key == "vendor") {
return ((x<y) ? -1 : ((x > y) ? 1: 0)) ;
} else {
return parseFloat(a.key) - parseFloat(b.key) ;
}
}) ;
}
function getProds() {
prods = [] ;
$q.all([promise1(),promise2(),promise3(),promise4(),promise5()]).then(function(response){
var z=0 ;
// process all results, ie: [0][{a:1,b:2,c:3},{a:4,b:5,c:6}], [1]:[{a:7,b:8,c:9}
for (var y=0;y<response.length;y++) {
// process individual result,ie: [{a:1,b:2,c:3},{a:4,b:5,c:6}]
for (var x=0;x<response[y].length;x++) {
response[y][x].prodID = z++ ; // reset prodID
prods.push(response[y][x]) ;
}
}
// sort option could be 'vendor','price','price_estimate'
prodInfo.sortBy = getDB("prod_sortOption") ;
sortProds(prodInfo.sortBy) ;
});
}
return {
all: function() {
return [prods,prodInfo.sortBy] ;
}
}
})
Because I can't get the above to work, I then tried auto-sorting the returned results in the controller, but it too is not working. In my controller:
$scope.doSort = function(key,prodList) {
prodList.sort(function(a,b) {
var x = a[key]; var y = b[key] ;
if (key == "vendor") {
return ((x<y) ? -1 : ((x > y) ? 1: 0)) ;
} else {
return parseFloat(a.key) - parseFloat(b.key) ;
}
}) ;
return prodList ;
}
var returnedProds = Products.all() ;
$scope.prods = $scope.doSort(prodInfo.sortBy,returnedProds[0]) ;
// $scope.prods is what is used to in my template to populate the web view.
HOWEVER, if the user in the webview does a manual sort on a button click that has ng-click="doSort('price',prods)" it works as intended...buts its the same doSort that isn't working on the auto-sorted returned results.
I hope all this makes sense. I can't figure out why its not sorting in the service...or again during the auto-sort upon returned results....but then does work when manually done. Ugh!
Unless I'm confused on your implementation, I recommend you don't have 2 functions that do the exact same thing. Use Products.sortProds() for both manual sorting and automatic sorting.
Here is my factory. I mocked the response array to return 1 product object from each promise. I overrided the getDB() call with a static string set to price. Also, I exposed every object and function in order to call getProds() from my component's $onInit, as I don't see your call to it. So the only difference is the synchronicity.
factory method
function ProductsFactory() {
return {
prods: [],
prodInfo: {},
all: function() {
return [this.prods,this.prodInfo.sortBy] ;
},
sortProds: function(key) {
this.prods.sort(function(a,b) {
var x = a[key]; var y = b[key] ;
if (key == "vendor") {
return ((x<y) ? -1 : ((x > y) ? 1: 0)) ;
} else {
return parseFloat(a[key]) - parseFloat(b[key]) ;
}
}) ;
},
getProds: function() {
this.prods = [] ;
var response = [
[{
"vendor": "Aaa Company",
"product" : "This prod",
"description" : "this cool prod",
"price" : 27.50,
"price_estimate" : 23.25,
"category" : "tool",
}],
[{
"vendor": "Zaa Company",
"product" : "This prod",
"description" : "this cool prod",
"price" : 22.90,
"price_estimate" : 23.25,
"category" : "tool",
}],
[{
"vendor": "Haa Company",
"product" : "This prod",
"description" : "this cool prod",
"price" : 20.20,
"price_estimate" : 23.25,
"category" : "tool",
}],
[{
"vendor": "Gaa Company",
"product" : "This prod",
"description" : "this cool prod",
"price" : 96.69,
"price_estimate" : 23.25,
"category" : "tool",
}],
[{
"vendor": "Waa Company",
"product" : "This prod",
"description" : "this cool prod",
"price" : 69.69,
"price_estimate" : 23.25,
"category" : "tool",
}],
];
var z=0 ;
// process all results, ie: [0][{a:1,b:2,c:3},{a:4,b:5,c:6}], [1]:[{a:7,b:8,c:9}
for (var y=0;y<response.length;y++) {
// process individual result,ie: [{a:1,b:2,c:3},{a:4,b:5,c:6}]
for (var x=0;x<Object.keys(response[y]).length;x++) {
response[y][x].prodID = z++ ; // reset prodID
this.prods.push(response[y][x]) ;
}
}
// sort option could be 'vendor','price','price_estimate'
//prodInfo.sortBy = getDB("prod_sortOption") ;
this.prodInfo.sortBy = 'price';
this.sortProds(this.prodInfo.sortBy) ;
},
}
The price won't sort unless you do:
return parseFloat(a[key]) - parseFloat(b[key]) ;
a.key => a[key]
b.key => b[key]
You also did not define the variables x and y in your sortProds() method
var x = a[key]; var y = b[key] ;
implementation
this.$onInit = function() {
Products.getProds();
Products.sortProds(Products.prodInfo.sortBy);
$scope.prods = Products.all()[0];
$scope.Products = Products; // expose to vm scope
console.log($scope.prods); // logs sorted array of product objects
}
I only had 30 minutes for this so I'm sorry if my answer is lacking. But for me, it works. If this doesn't work for you still, make sure your promises are returning the correct data in the correct format (2d array).

How to access node in the firebase databse

My aim is to have each user select a total of 6 players. when each player is selected, the player id is sent to a node on the database called 'total'using the push () method. The code is written below
var ref = firebase.database().ref().child('players');
var ref3 = firebase.database().ref().child('users').child(uid).child('total');
$scope.players = $firebaseArray(ref);
console.log ($scope.players);
$scope.history = [];
$scope.buy = function(player) {
//remove if already added locally
var index = $scope.history.indexOf(player);
if(index>=0){
$scope.history.splice(index,1);
return;
}
//remove if already added on firebase
//max 6 allowed
if($scope.history.length>=6){
alert('max 6 allowed');
return;
}
var selected = $scope.history.reduce(function(a,b){
a[b.position] = (a[b.position] || 0) + 1;
return a;
}, {}) || {};
if(!selected[player.position] || selected[player.position]<2){
$scope.history.push(player);
ref3.push(player.id);
}else{
alert('You can add only two players per position');
}
};
$scope.getTotal = function(){
return $scope.history.reduce(function(tot, p){
tot = tot - p.price;
return tot;
}, $scope.total);
};
this is how the database is structured :
{
"players" : [ {
"R" : 0,
"Team" : "Industry",
"Y" : 0,
"assists" : 0,
"goals" : 0,
"id" : 1,
"name" : "Yasin 'YB' Amusan",
"position" : "forward",
"price" : 8000000
}, {
"R" : 0,
"Team" : "Industry",
"Y" : 0,
"assists" : 0,
"goals" : 0,
"id" : 2,
"name" : "Hassan 'Hasi' Akinyera",
"position" : "defender",
"price" : 5000000
}],
"users" : {
"l3J1TVsFNLMi0Oxg6hz4AJpacE53" : {
"email" : "awoniyideji#yahoo.com",
"fullname" : "Djflex11",
"teamname" : "deji awoniyi",
"total" : {
"-Kpl19z_25IEhiCEFrui" : 1,
"-Kpl1ARqT-v_btJ7OAq2" : 2,
"-Kpl1AsdodYWVPWWd5xA" : 2,
"-Kpl1iN7a7PLU-tnkKc4" : 1,
"-Kpl1j5CtN6c_mnmWLP-" : 1,
"-Kpl1k0BNCP5NNFV5uX6" : 1
},
"userName" : "awoniyideji#yahoo.com",
"week" : "no",
}
}
}
My ISSUE
The aim is that a player cannot be selected twice by the same user. MY code currently prevents a player from being selected twice locally, but the same player id can be pushed to the firebase database. My issue is how to basically check the total node so that the selected player if already "pushed" into database, will be removed instead of inserted into the database. I know that 'indexOf' is to be avoided with firebase.
This should work:
if(ref3.toJSON().hasOwnProperty(playerId)){
ref3.child(playerId).remove();
}
References:
Check for key in JSON
Remove from DB

Underscore sortBy algorithm

I need your help for a little algorithme for my app :
i have an object like this :
var obj = { "response" : [
"candidate" : {
"id":"1",
"price" : 10,
"distance" : 20
},
"candidate" : {
"id":"2"
"price" : 14,
"distance" : 2
},
"candidate" : {
"id":"3",
"price" : 200,
"distance" : 1
}
] }
Which i sort by price like this :
var sortPrice = _(obj.response).sortBy(function(p){
return p.candidate.price
})
It works fine and sort the object (ids) : 1,2,3
Now if candidate has the same price but different distance, i should show first candidate with the same price and the lowest distance :
var obj = { "response" : [
"candidate" : {
"id":"1",
"price" : 10,
"distance" : 20
},
"candidate" : {
"id":"2"
"price" : 10,
"distance" : 2
},
"candidate" : {
"id":"3",
"price" : 200,
"distance" : 1
}
] }
var sorted = _(obj.response).chain().sortBy(function (p) {
return parseInt(p.candidate.price) ;
}).sortBy(function(d){
return parseInt(d.candidate.distance)
}).value();
But it sort me the lowest distance first (ids) : 3(with distance 1), 2(with distance 2), 1(with distance 20) than 2,1,3
Do you have any suggestion?
Thank you.
In pure js you can use sort() like this.
var obj = {
"response": [{
"candidate": {
"id": "1",
"price": 8,
"distance": 20
}
}, {
"candidate": {
"id": "2",
"price": 8,
"distance": 2
}
}, {
"candidate": {
"id": "3",
"price": 200,
"distance": 1
}
}]
}
obj.response.sort(function(a, b) {
return a.candidate.price - b.candidate.price || a.candidate.distance - b.candidate.distance;
})
console.log(obj.response)
Lodash is a fork of underscore that allows you to sort by several properties of the object.
Using it, a solution could be:
_(obj.response).map(_.partial(_.get, _, 'candidate')).sortBy(['price', 'distance']).value();
Here's the fiddle in case you want to play with it.

Categories