Loop on array and delete objects with specific value - node.js

I have an array similar than this one, called websiteproducts:
[{
"memberid": 280,
"state": "AL",
"product": "1",
"deleteProduct": 1,
"waitingDays": 0
},
{
"memberid": 280,
"state": "AL",
"product": "2",
"deleteProduct": 1,
"waitingDays": 0
},
{
"memberid": 280,
"state": "AL",
"product": "3",
"deleteProduct": 1,
"waitingDays": 0
},
{
"memberid": 280,
"state": "AL",
"product": "4",
"deleteProduct": 0,
"waitingDays": 0
}
]
And Im trying to delete all objects that have "deleteProduct" = 1 as follows:
for (let i = 0; i < websiteproducts.length; i++) {
if (websiteproducts[i].deleteProduct == 1) {
websiteproducts.splice(i, 1)
}
}
But only the first object is deleted.
I believe it has to do with the fact that Im deleting the item from the array on the fly.
But this one works, when copying the objects to a new array:
let finalProducts = []
for (let i = 0; i < websiteproducts.length; i++) {
if (websiteproducts[i].deleteProduct != 1) {
finalProducts.push(websiteproducts[i])
}
}
Is there a way to delete the objects straight from the array through a loop, without having to create a second array?
Thanks.

You can use the filter function on the array, it only returns the elements that meet the condition.
let finalProd = websiteproducts.filter(prod => prod.deleteProduct != 1)

You don't have to use a loop at all. You can use Array.prototype.filter().
This returns a new array with the filtered elements removed:
const filtered = websiteproducts.filter(product => product.deleteProduct != 1);

You must decrement the index variable after splice like this :
websiteproducts.splice(i, 1);
i--;

Related

Python nested json

Can any one have solution for this, i want there should be api data in this manner ??
I wanted api data in for similar state comes in one hood rather than seprate, different state data can be different obj,
data = [{
state_name:New_jersi, data:{
category:Phishing,
sub_cat_data:[{
name:SubCat1,
count:20
},
{
name:SubCat2,
count:30
}]
}
category: malware,
sub_cat_data:[{
name:SubCat1,
count:20
},
{
name:SubCat2,
count:30
}]
},
{
state_name:Washinton, data:{
category:Phishing,
data:[{
name:SubCat1,
count:20
},
{
name:SubCat2,
count:30
}]
}
}]
But may api response be:
{
"state": "South Carolina",
"state_count": 2,
"Website Compromise/Intrusion": {
"sub_category": {
"Insecure Direct Object Reference": 2,
"Memory Corruption": 2,
"SQLI": 1,
"Stack Overflow": 1,
"XSRF": 1,
"Heap Overflow": 1,
"Security Misconfiguration": 1
}
}
},
{
"state": "South Carolina",
"state_count": 1,
"Phishing": {
"sub_category": {
"Spear Phishing Attacks": 2,
"Fast Flux": 2,
"Rock fish": 2,
"Identify Theft/Social Engineering": 1,
"Phishing Redirector": 1,
"Pharming": 1,
"Exploitation of Hardware Vulnerability": 1
}
}
},
i wanted same state data be in same object buut in my case state data comes in seprate object because of data comes through category, rather that seprate.
My logic are below
cat_count = incnum.values('incident_category__cat_name','incident_category__cat_id').annotate(count=Count('incident_category__cat_id'))
subcat_count = incnum.values('incident_sub_category__sub_cat_name','incident_sub_category__cat_id','incident_sub_category__id').annotate(count=Count('incident_sub_category__cat_id'))
reporter_state_count1 = incnum.values('incident_category__cat_id','reporter__comp_individual_state','reporter__comp_individual_state__name').annotate(count=Count('incident_category__cat_id'))
for x, state_ in enumerate(reporter_state_count1):
for i, cat_ in enumerate(cat_count):
if state_['incident_category__cat_id'] == cat_['incident_category__cat_id']:
for i, cat_ in enumerate(cat_count):
if state_['incident_category__cat_id'] == cat_['incident_category__cat_id']:
arr16.append({'state':state_['reporter__comp_individual_state__name'], 'state_count':state_['count'], cat_['incident_category__cat_name']:{'sub_category':{}}})
for sub_ in subcat_count:
if cat_['incident_category__cat_id'] == sub_['incident_sub_category__cat_id']:
arr16[i][cat_['incident_category__cat_name']]['sub_category'].update({sub_['incident_sub_category__sub_cat_name']:sub_['count']})
cat_count = incnum.values('incident_category__cat_name', 'incident_category__cat_id').annotate(
count=Count('incident_category__cat_id'))
subcat_count = incnum.values('incident_sub_category__sub_cat_name', 'incident_sub_category__cat_id',
'incident_sub_category__id').annotate(count=Count('incident_sub_category__cat_id'))
reporter_state_count1 = incnum.values('incident_category__cat_id', 'reporter__comp_individual_state',
'reporter__comp_individual_state__name').annotate(
count=Count('incident_category__cat_id'))
arr16 = []
for state_ in reporter_state_count1:
state_data = {"state_name" : state_['reporter__comp_individual_state__name'], "data":[]}
for cat_ in cat_count:
if state_['incident_category__cat_id'] == cat_['incident_category__cat_id']:
sub_cat_data = [{sub_['incident_sub_category__sub_cat_name']: sub_['count']} for sub_ in subcat_count if cat_['incident_category__cat_id'] == sub_['incident_sub_category__cat_id']]
category_data = {"category": cat_['incident_category__cat_name'], "sub_cat_data": sub_cat_data}
state_data["data"].append(category_data)
arr16.append(state_data)
1 State might have multiple category, the way you are trying to make your api, it won't be able to show multiple category for a state. This is why i modify a little bit. you will find all the category in state object
Edit
Creating a dictionary which will store category_id as key and all the subcategory of that category as value
cat_to_subcat_list = {}
for cat_ in cat_count:
sub_cat_data = [{"name":sub_['incident_sub_category__sub_cat_name'],"count": sub_['count']} for sub_ in subcat_count if
cat_['incident_category__cat_id'] == sub_['incident_sub_category__cat_id']]
cat_to_subcat_list[cat_['incident_category__cat_id']] = {"category": cat_['incident_category__cat_name'], "sub_cat_data": sub_cat_data}
Createing a dictionary which will store state__name as key and a list of category object will save as value
state_data = {}
for state_ in reporter_state_count1:
if state_['reporter__comp_individual_state__name'] not in state_data:
'''This if statement is checking whether state_name exit or not.
if state_name does not exist in dictionary it'll create a empty list as it's value'''
state_data[state_['reporter__comp_individual_state__name']] = []
state_data[state_['reporter__comp_individual_state__name']].append(cat_to_subcat_list[state_['incident_category__cat_id']])
Re-formatting json as api needed
arr16 = [
{
"state_name": state_name,
"data": state_data
}for state_name, state_data in state_data.items()
]

How can I return all nested objects using python?

I wrote an Elastic query which will check the condition (status="APPROVED") and Gets all approved_by objects.
This is my index (portfolio):
{
"settings": {},
"mappings": {
"portfolio": {
"properties": {
"status": {
"type": "keyword",
"normalizer": "lcase_ascii_normalizer"
},
"archived_at": {
"type": "date"
},
"approved_by": {
"id": "text",
"name":"text"
}
}
}
}
}
Currently I have 60 objects whose status are approved , so when i run the query it will show 60 objects,but in my case i am getting only one object(I debugged the code, total 60 objects are coming as expected, but still returning only single object), please help guys.
My query:
profiles = client.search(index='portfolio', doc_type='portfolio',
scroll='10m', size=1000,
body={
"query": {"match": {"status": "APPROVED"}}
})
sid = profiles['_scroll_id']
scroll_size = len(profiles['hits']['hits'])
while scroll_size > 0:
for info in profiles['hits']['hits']:
item = info['_source']
approved_by_obj = item.get('approved_by')
if approved_by_obj:
return (jsonify({"approved_by": approved_by_obj}))
Expected o/p format:
{
"approved_by": {
"id": "system",
"name": "system"
}
}
You're getting only one result because you're returning from your loop, effectively breaking out of it completely.
So, instead of returning from it, append the found approved_by_object to a list of your choice and then return that 60-member list:
profiles = client.search(index='portfolio', doc_type='portfolio',
scroll='10m', size=1000,
body={
"query": {"match": {"status": "APPROVED"}}
})
sid = profiles['_scroll_id']
scroll_size = len(profiles['hits']['hits'])
approved_hits_sources = [] # <-- add this
while scroll_size > 0:
for info in profiles['hits']['hits']:
item = info['_source']
approved_by_obj = item.get('approved_by')
if approved_by_obj:
approved_hits_sources.append({"approved_by": approved_by_obj}) # <--- append and not return
return jsonify({"approved_hits_sources": approved_hits_sources})

ArangoDB query returns extra items with diacritic marks

I have the question that is related to diacritic marks. For the sake of simplicity, let's assume, I have a document collection "c". I put two documents:
{"uri": "/c/de/aërotropismus/"}, {"uri": "/c/de/aerotropismus/"}
As you see, they are almost the same, except for the diacritic mark.
Then, I create a persistent index on the field "uri".
After this I do the query:
for doc in c
filter doc.uri >= "/c/de/aerotropismus/" and doc.uri < "/c/de/aerotropismus0"
return doc
I expect this query to return one result, but I get two results:
[
{
"_key": "37070873",
"_id": "c/37070873",
"_rev": "_bHsOMnm---",
"uri": "/c/de/aerotropismus/"
},
{
"_key": "37070853",
"_id": "c/37070853",
"_rev": "_bHsO_m6---",
"uri": "/c/de/aërotropismus/"
}
]
Why is that? And how can I fix it so that it returns just one result:
[
{
"_key": "37070873",
"_id": "c/37070873",
"_rev": "_bHsOMnm---",
"uri": "/c/de/aerotropismus/"
}
]
This indeed seems like a bug:
FOR doc IN c
SORT doc.uri DESC
RETURN KEEP(doc, ['uri'])
Results:
[
{
"uri": "/c/de/aerotropismus/1"
},
{
"uri": "/c/de/aërotropismus/"
},
{
"uri": "/c/de/aerotropismus/"
}
]
Workaround
You can create a user defined function inside ArangoDB to sort an array of strings.
More reading:
Registering an AQL user function
Workaround Implementation
You can execute the following code in aragosh to register your custom function:
const aqlfunctions = require("#arangodb/aql/functions");
function isBetween(elems, left, right) {
const sorted = elems.sort();
const leftIndex = sorted.findIndex((elem) => elem >= left);
if (leftIndex === -1) {
return [];
}
const rightIndexReversed = sorted.slice().reverse().findIndex((elem) => elem < right);
if (rightIndexReversed === -1) {
return [];
}
const rightIndex = sorted.length - rightIndexReversed - 1;
if (leftIndex > rightIndex) {
return [];
}
return sorted.slice(leftIndex, rightIndex + 1);
}
aqlfunctions.register("CUSTOM::IS_BETWEEN", isBetween, true);
You can later run your AQL as this:
RETURN CUSTOM::IS_BETWEEN((FOR rec IN c RETURN rec.uri), "/c/de/aerotropismus/", "/c/de/aerotropismus0")
It will return only one record for the dataset you provided.

How to get the position of an object in an array?

I'm trying to get the position in array of the first object so i can delete it with a function. The problem is: i don't know how to get the "index"value.
{
"2": {
"nome": "sou1",
"email": "adsa#lala.com",
"gênero": "masculino",
"id": 1,
"pos": 0
},
"3": {
"nome": "sou1",
"email": "adsa#lala.com",
"gênero": "masculino",
"id": 1,
"pos": 1
}
}
In this case, my output would be 2.
You can try the below
var someObject={
"2": {
"nome": "sou1",
"email": "adsa#lala.com",
"gênero": "masculino",
"id": 1,
"pos": 0
},
"3": {
"nome": "sou1",
"email": "adsa#lala.com",
"gênero": "masculino",
"id": 1,
"pos": 1
}};
console.log(Object.keys(someObject)[0]);
delete someObject[Object.keys(someObject)[0]];
console.log(someObject);
There is no ordering in JSON objects.
However, for your use case (if I correctly understand that), you can convert the JSON object into an array doing...
const someObject = {
a: "A",
b: "B",
c: "C"
}
const keys = Object.keys(someObject);
console.log(keys); // array of keys
let arr = [];
for(key of keys) {
arr.push(someObject[key]);
}
console.log(arr); // array of objects
...where the index of an element in the keys array (a key in your original JSON object) will be identical to the index of an element in the arr array (the corresponding value for that key in your original JSON object) which it maps to in your original JSON object, in a way giving you what you probably are looking for. Then you can access them using the array indices.
Hope this helps :)

Dojo AccordionContainer.addChild doesn't work for more than 2 children

I want to add programatically 4 children to dijit.layout.AccordionContainer. The script runs with no errors, but it only adds 2 children, no matter how I try to achieve this. From my debug using firebug it looks like the scripts stops after adding second child. I tried following suggestions from here, here and here, but I found no solution.
Some code:
AccordionContainer definition:
var listaWyjazdow = new dijit.layout.AccordionContainer({}, "target-lista-wyjazdow");
listaWyjazdow.startup();
aktualizujListeWyjazdow();
function to add 4 children to AccordionContainer:
function aktualizujListeWyjazdow(){
dojo.require("dijit.layout.AccordionPane");
var lista = dijit.byId('target-lista-wyjazdow');
lista.destroyDescendants();
var tablica = new dojo.data.ItemFileReadStore({
url: "logika/getJSON/getWyjazdy.php",
clearOnClose: true,
urlPreventCache: true
}).fetch({
query: {id: '*'},
sort: {attribute: 'data', descending: true},
start: 0,
count: 4,
onComplete: function(dane){
console.log(dane);
var ile = dane.length;
var i = 0;
var dzieci = new Array();
//this works for 2 children only:
for (i = 0; i < ile; i++){
var szczegoly = 'Klient: <strong>' + dane[i].klient + '</strong></br>';
szczegoly += 'Osoba wyjeżdżająca: <strong>' + dane[i].wyjezdzajacy + '</strong></br>';
dzieci[i] = new dijit.layout.AccordionPane({
id: "wyjazd" + i,
title: "Wyjazd: " + dane[i].data,
content: szczegoly
});
console.log(dane[i]);
console.log(i + ' - ' + ile);
lista.addChild(dzieci[i], 0);
lista.selectChild(dijit.byId('wyjazd' + i));
//console.log(lista);
}
//this works for 2 children only:
/*lista.addChild(dzieci[0]);
console.log(0);
lista.addChild(dzieci[1]);
console.log(1);
lista.addChild(dzieci[2]);
console.log(2);
lista.addChild(dzieci[3]);
console.log(3);*/
//this outputs all children:
/*console.log(dzieci[0]);
console.log(dzieci[1]);
console.log(dzieci[2]);
console.log(dzieci[3]);*/
//this works for 2 children only:
/*for (i = 0; i < ile; i++){
lista.addChild(dzieci[i]);
console.log(dzieci[i]);
}*/
}
});
}
console output (from firebug):
[Object { id=[1], etykieta=[1], data=[1], more...}, Object { id=[1], etykieta=[1], data=[1], more...}, Object { id=[1], etykieta=[1], data=[1], more...}, Object { id=[1], etykieta=[1], data=[1], more...}]
Object { id=[1], etykieta=[1], data=[1], more...}
0 - 4
Object { id=[1], etykieta=[1], data=[1], more...}
1 - 4
Any help would be greatly appreciated!
EDIT
a little update:
in my ItemFileReadStore object value returned by url is json:
{
"identifier": "id",
"label": "etykieta",
"items": [
{
"id": "1",
"etykieta": "Wyjazd0",
"data": "06-10-2011",
"wyjezdzajacy": "cblajszczak",
"idKlienta": "1",
"klient": "klient testowy",
"zadanieQS": null,
"dataKolejnegoWyjazdu": null,
"lacznyCzasWyjazdu": "0"
},
{
"id": "3",
"etykieta": "Wyjazd1",
"data": "15-11-2011",
"wyjezdzajacy": "cblajszczak",
"idKlienta": "1",
"klient": "klient testowy",
"zadanieQS": null,
"dataKolejnegoWyjazdu": null,
"lacznyCzasWyjazdu": "0"
},
{
"id": "5",
"etykieta": "Wyjazd2",
"data": "30-11-2011",
"wyjezdzajacy": "cblajszczak",
"idKlienta": "1",
"klient": "klient testowy",
"zadanieQS": null,
"dataKolejnegoWyjazdu": null,
"lacznyCzasWyjazdu": "0"
},
{
"id": "4",
"etykieta": "Wyjazd3",
"data": "24-11-2011",
"wyjezdzajacy": "cblajszczak",
"idKlienta": "2",
"klient": "hfhhfhd",
"zadanieQS": null,
"dataKolejnegoWyjazdu": null,
"lacznyCzasWyjazdu": "0"
}
]
}
dane[2] has following structure (taken from firebug):
_0 2
_RI true
_S Object { _arrayOfAllItems=[4], _arrayOfTopLevelItems=[4], _loadFinished=true, more...}
data ["30-11-2011"]
[other fields from json structure]
I have noticed that _S shown above contains whole dane array. And this dane contains another _S with whole dane array. And so on, recursively - could this be the problem?
I finally managed to solve my problem. In case anyone else encounters similar problem, the solution is to create container (AccordionContainer in this case) declaratively, not programmatically:
<div id="id" style="height:50%" dojoType="dijit.layout.AccordionContainer"></div>

Resources