I have this array:
[
{
type: "hhh",
items: [
{
"name": "EGFR",
"type": "a",
"selected": true
}
]
},
{
type: "aaa",
items: [
{
"name": "mm",
"type": "b",
"selected": false
}
]
},
{
type: "ii",
items: [
{
"name": "pp",
"type": "bb",
"selected": true
}
]
}
]
I want to show a counter of the items with selected property "true".
I want it to be changed real time when change.
(Without watch and function)
Thnaks!
Here is the way:
var current_selected = {
get amount(){
var res = 0;
arr.forEach(function(item, i, arr) {
if (item.items[0].selected) res++;
})
return res;
}
}
Calling:
current_selected.amount
Fiddle
You can use JsonPath to get the count. Also using JsonPath has an added advantage of working on complex json structure. For the example you gave, you just need to include jsonpath js file and use the following in your script:
console.log(arr);
var filtered = jsonPath(arr, "$.[*].items[?(#.selected==true)]");
console.log(filtered);
console.log(filtered.length);
where arr is your json structure.
JsonPath can be got from :
https://code.google.com/archive/p/jsonpath/downloads
JsonPath help:
http://goessner.net/articles/JsonPath/
There might be updated version in other sources but that was the one I had worked on
Related
I am fetching data from an api that, sometimes, gives me multiple objects with the same values, or very similar values, which I want to remove.
For example, I might get back:
[
{
"Name": "blah",
"Date": "1992-02-18T00:00:00.000Z",
"Language": "English",
},
{
"Name": "blahzay",
"Date": "1998-02-18T00:00:00.000Z",
"Language": "French",
}, {
"Name": "blah", // same name, no problem
"Date": "1999-02-18T00:00:00.000Z", // different date
"Language": "English", // but same language
},
]
So I want to check that no two objects have a key with the same "Language" value (in this case, "English").
I would like to get the general process of filtering out the entire object if it's "Language" value is duplicated, with the extra issue of not having the same number of objects returned each time. So, allowing for dynamic number of objects in the array.
There is an example here:
Unexpeected result when filtering one object array against two other object arrays
but it's assuming that you have a set number of objects in the array and you are only comparing the contents of those same objects each time.
I would be looking for a way to compare
arrayName[eachObject].Language === "English"
and keep one of the objects but any others (an unknown number of objects) should be filtered out, most probably using .filter() method along with .map().
The below snippets stores the languages that have been encountered in an array. If the current objects language is in the array then it is filtered out. It makes the assumption that the first object encountered with the language is stored.
const objs = [
{
"Name": "blah",
"Date": "1992-02-18T00:00:00.000Z",
"Language": "English",
},
{
"Name": "blahzay",
"Date": "1998-02-18T00:00:00.000Z",
"Language": "French",
}, {
"Name": "blah", // same name, no problem
"Date": "1999-02-18T00:00:00.000Z", // different date
"Language": "English", // but same language
},
],
presentLanguages = [];
let languageIsNotPresent;
const objsFilteredByLanguage = objs.filter(function (o) {
languageIsNotPresent = presentLanguages.indexOf(o.Language) == -1;
presentLanguages.push(o.Language);
return languageIsNotPresent;
});
console.log(objsFilteredByLanguage);
You could take a hash table and filter the array by checking Name and Language.
var array = [{ Name: "blah", Date: "1992-02-18T00:00:00.000Z", Language: "English" }, { Name: "blahzay", Date: "1998-02-18T00:00:00.000Z", Language: "French" }, { Name: "blah", Date: "1999-02-18T00:00:00.000Z", Language: "English" }],
hash = {},
result = array.filter(({ Name, Language }) => {
var key = `${Name}|${Language}`;
if (!hash[key]) return hash[key] = true;
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Using Set makes it easy to remove duplicates for as many keys as you like. I tried to be as verbose as possible so that each step was clear.
var objects = [{ "Name": "blah", "Date": "1992-02-18T00:00:00.000Z", "Language": "English", }, { "Name": "blah", "Date": "1998-02-18T00:00:00.000Z", "Language": "French", }, { "Name": "blah", "Date": "1999-02-18T00:00:00.000Z", "Language": "English" }];
function uniqueKeyVals(objects, key) {
const objVals = objects.map(object => object[key]); // ex. ["English", "French", "English"]
return objects.slice(0, new Set(objVals).size); // ex. { "English", "French" }.size = 2
}
function removeKeyDuplicates(objects, keys) {
keys.forEach(key => objects = uniqueKeyVals(objects, key));
return objects;
}
// can also use uniqueKeyVals(key) directly for just one key
console.log("Unique 'Language': \n", removeKeyDuplicates(objects, ["Language"]));
console.log("Unique ['Language', 'Name']: \n", removeKeyDuplicates(objects, ["Language", "Name"]));
I would use the underscore module for JavaScript and the unique function in this scenario. Here is a sample array of data objects:
let data = [{
name: 'blah',
date: Date.now(),
language: "en"
},
{
name: 'noblah',
date: Date.now(),
language: 'es'
},
{
name: 'blah',
date: Date.now(),
language: 'en'
}];
Then we can use the unique function in the underscore library to only return a copy of the data that has unique values associated with the language key:
const result = _.unique(data, 'language');
I have the following array containing objects, And there are arrays in the objects too.
let array = [
{
"data": {
"Game": {
"Game_number": [
"4",
"6",
"8"
],
"Game_name": [
"Name_1",
"Name_2",
"name_3"
]
},
"AA": {
"AA_count": [
"30"
],
"AA_name": [
"Umbrella"
]
},
}
}
]
Now i have to put them in database, Each have a column against.
But the issue is that the above data is not constant, So i cannot put them via their indexes. if the data is missing for a column than that's fine it will go empty
I tried via for each but that is inserting the last element of the array.
array.data.forEach((item) => {
const Games = Parse.Object.extend('Games');
const query = new Games();
item.data.Game.Game_number.forEach((number) => {
query.set('game_number', number);
}, this);
item.data.Game.Game_name.forEach((name) => {
query.set('game_name', name);
}, this);
query.save();
}, this);
What will be a flexible way to handle it ?
I have 2 array objects in Angular JS that I wish to merge (overlap/combine) the matching ones.
For example, the Array 1 is like this:
[
{"id":1,"name":"Adam"},
{"id":2,"name":"Smith"},
{"id":3,"name":"Eve"},
{"id":4,"name":"Gary"},
]
Array 2 is like this:
[
{"id":1,"name":"Adam", "checked":true},
{"id":3,"name":"Eve", "checked":true},
]
I want the resulting array after merging to become this:
[
{"id":1,"name":"Adam", "checked":true},
{"id":2,"name":"Smith"},
{"id":3,"name":"Eve", "checked":true},
{"id":4,"name":"Gary"},
]
Is that possible? I have tried angular's array_merge and array_extend like this:
angular.merge([], $scope.array1, $scope.array2);
angular.extend([], $scope.array1, $scope.array2);
But the above method overlap the first 2 objects in array and doesn't merge them based on matching data. Is having a foreach loop the only solution for this?
Can someone guide me here please?
Not sure if this find of merge is supported by AngularJS. I've made a snippet which does exactly the same:
function merge(array1, array2) {
var ids = [];
var merge_obj = [];
array1.map(function(ele) {
if (!(ids.indexOf(ele.id) > -1)) {
ids.push(ele.id);
merge_obj.push(ele);
}
});
array2.map(function(ele) {
var index = ids.indexOf(ele.id);
if (!( index > -1)) {
ids.push(ele.id);
merge_obj.push(ele);
}else{
merge_obj[index] = ele;
}
});
console.log(merge_obj);
}
var array1 = [{
"id": 1,
"name": "Adam"
}, {
"id": 2,
"name": "Smith"
}, {
"id": 3,
"name": "Eve"
}, {
"id": 4,
"name": "Gary"
}, ]
var array2 = [{
"id": 1,
"name": "Adam",
"checked": true
}, {
"id": 3,
"name": "Eve",
"checked": true
}, ];
merge(array1, array2);
Genuinely, extend in Angular works with object instead of array. But we can do small trick in your case. Here is another solution.
// a1, a2 is your arrays
// This is to convert array to object with key is id and value is the array item itself
var a1_ = a1.reduce(function(obj, value) {
obj[value.id] = value;
return obj;
}, {});
var a2_ = a2.reduce(function(obj, value) {
obj[value.id] = value;
return obj;
}, {});
// Then use extend with those two converted objects
var result = angular.extend([], a1_, a2_).splice(1)
Notes:
For compatibility, reduce may not work.
The after array will replace the previous one. This is because of implementation of extend in Angular.
I have an JSON array like this
var filter_value_data = [{"Status":[{"name":"Open","id":"1"},{"name":"Pending","id":"2"},{"name":"Resolved","id":"3"},{"name":"Closed","id":"4"},{"name":"Evaluation","id":"5"}]},{"Payment Status":[{"name":"Paid","id":"10"},{"name":"UnPaid","id":"11"},{"name":"Part Paid","id":"12"}]},{"Priority":[{"name":"Low","id":"6"},{"name":"Medium","id":"7"},{"name":"High","id":"8"},{"name":"Urgent","id":"9"}]}]
I have tried filter_value_data["Status"] which is obviously wrong. How do I get the JSON elements for Status using the names like Status,Payment Status?
filter_value_data is an array (having []), so use filter_value_data[0].Status to get the first element-object with property "Status".
It is always good to format your code in order to see the hierarchy of the structures:
var filter_value_data = [
{
"Status": [
{
"name": "Open",
"id": "1"
}, {
"name": "Pending",
"id": "2"
}, ...
]
}, {
"Payment Status": [
{
"name": "Paid",
"id": "10"
}, ...
]
}, {
"Priority": [
{
"name": "Low",
"id": "6"
}, ...
]
}
];
With your current JSON you can't get the elements with the name alone.
You can get Status with filter_value_data[0]['Status'] and Payment status with filter_value_data[1]['Payment Status'].
This is because the keys are in seperate objects in the array.
In order to get them with filter_value_data['Status'] you need to change your JSON to
var filter_value_data = {
"Status":[
{"name":"Open","id":"1"},
{"name":"Pending","id":"2"},
{"name":"Resolved","id":"3"},
{"name":"Closed","id":"4"},
{"name":"Evaluation","id":"5"}
],
"Payment Status":[
{"name":"Paid","id":"10"},
{"name":"UnPaid","id":"11"},
{"name":"Part Paid","id":"12"}
],
"Priority":[
{"name":"Low","id":"6"},
{"name":"Medium","id":"7"},
{"name":"High","id":"8"},
{"name":"Urgent","id":"9"}
]
};
I wrote this on my phone so it's not as well-formatted as usual. I'll change it ASAP.
With your current JSON, created a result which might be helpful for you.
JS:
$.each(filter_value_data,function(ind,val){
var sta = val.Status; // Status Object get displayed
for(var i=0;i<sta.length;i++){
var idVal= sta[i].id;
var nameVal = sta[i].name;
Statusarray.push(idVal,nameVal);
console.log(Statusarray);
}
})
FiddleDemo
You can use below code, it will return status object
filter_value_data[0]['Status']
filter_value_data[0]['Payment Status']
to get Single value you use :
filter_value_data[0]['Status'][0]['name']
Im new to JSON and I have to deal with a complex one.
Please see image below:
It has an error:
I don't know how to properly separate the 2 json arrays. I even tried to use : instead of , on line 18 but I still get errors. BTW, I use http://jsonlint.com/ to validate.
On line 2 you gave a key, but failed to do so on line 19. You have to keep the structure.
Remove the key on line 2, they shouldn't be used for arrays in that way.
Edit: In addition, you are trying to put arrays right in objects, switch the opening and ending object marks ({}) with ([]) for arrays on your first and last line.
[
[
{...},
{...},
...
{...}
],
[
{...},
{...},
...
{...}
],
...
[
{...},
{...},
...
{...}
]
]
I believe the correct way to build this JSON should be:
{
"glEntries": [
{
"generalLedgerId":1,
"accountId": 34,
"amount" : 32334.23,
"descripction": "desc1",
"debit" : "Yes"
},
{
"generalLedgerId":2,
"accountId": 35,
"amount" : 323.23,
"descripction": "desc",
"debit" : "Yes"
},
...
]
}
There are many ways to construct JSON data, but it depends on your data and the way you want to present it. Here are a couple examples - hope it helps:
{
"glEntries": [
{
"object1-prop1": "one"
},
{
"object2-prop1": 1,
"object2-prop2": "two"
},
{
"object3-prop1": [
"a",
"r",
"r",
"a",
"y"
],
"object3-prop1.1": "string"
}
],
"otherEntries": [
{
"objectx": "x"
},
{
"objecty": "y"
},
{
"objectz": [
1,
2,
3,
4
]
}
],
"oneEntry": "json"
}
Other Example:
[
{
"obj1-prop": 222
},
{
"obj2-prop": "object2"
},
{
"obj3-prop": "Object3"
},
[
"a",
"r",
"r",
"a",
"y",
777,
888
],
"string",
178,
{
"objectProp": "testing123"
}
]
You have more {} than needed and will make parsing your JSON more difficult:
Structure will work a lot better like this:
{"glentries":[
{ "property1":"value", "property2" : "value",..... "lastProperty": "value"},
{ "property1":"value", "property2" : "value",..... "lastProperty": "value"},
{ "property1":"value", "property2" : "value",..... "lastProperty": "value"}
]
}
Now glentries is an array of objects that have multiple properties to them.
alert( glentries[0].property2 )
The parent structure is an Object, so it is expecting a string Key for the second array. It it's supposed to be an array of arrays, you should be using an array and not an Object.