Remove Member for rapid JSON nested objects - rapidjson

Are there examples to remove a member within a nested JSON object?
For example: Consider the below JSON snippet, how would I be able to remove member C from the rapid son library?
{
"a": 1,
"b":{"c" : 2, "d" : 3}
}
I am not looking for hardcoded removal.. Like a.RemoveMember("c"); I am looking for code examples to remove a member from a rapid JSON document using the member iterator.
All the examples I see are for ConstMemberIterator. But RemoveMember can only be called with Member Iterators
From the document https://rapidjson.org/md_doc_tutorial.html, I am looking for an examples code snippet for the following function:
MemberIterator RemoveMember(MemberIterator): Remove a member by iterator (constant time complexity).
MemberIterator EraseMember(MemberIterator): similar to the above but it preserves order of members (linear time complexity).
MemberIterator EraseMember(MemberIterator first, MemberIterator last): remove a range of members, preserves order (linear time complexity).

I don't know if this can resolve your issue or not
(http://rapidjson.org/md_doc_pointer.html)
// Erase a member or element, return true if the value exists
bool success = Pointer("/b/c").Erase(d);
assert(success);
Edited
Yes, but it will erase the entire b object. The result will be {"a": 1}

Related

Building a std::map and issue with using std::emplace

Code:
std::map<CString, S_DISCUSSION_HIST_ITEM> mapHistory;
// History list is in ascending date order
for (auto& sHistItem : m_listDiscussionItemHist)
{
if (m_bFullHistoryMode)
mapHistory.emplace(sHistItem.strName, sHistItem);
else if (sHistItem.eSchool == m_eActiveSchool)
mapHistory.emplace(sHistItem.strName, sHistItem);
}
// The map is sorted by Name (so reset by date later)
// The map has the latest assignment info for each Name now
Observation:
I now understand that std::emplace behaves like this:
The insertion only takes place if no other element in the container has a key equivalent to the one being emplaced (keys in a map container are unique).
Therefore my code is flawed. What I was hoping to acheive (in pseudo code) is:
For Each History Item
Is the name in the map?
No, so add to map with sHitItem
Yes, so replace the sHistItem with this one
End Loop
By the end of this loop iteration I want to have the most recent sHitItem, for each person. But as it is, it is only adding an entry into the map if the name does not exist.
What is the simplest way to get around this?
Use insert_or_assign method if the item is assignable. It will be assigned if it already exists. Or use [] operator followed by assignment, it will default-construct item if it does not exist.
For non-assignable types I'm afraid there's no convenient way.

How to initialize object attributes from an array of strings in Python?

I am supposed to write a class which will allow the user of the script to define what attributes will it's objects have when initializing them by giving it an array of strings like this.
data = Database(tables=['distance', 'speed'])
Then it should be possible to call the class's methods like
data.distance.insert({1: 25, 2: 55})
data.speed.mean()
etc.
I have tried using setattr() this way
data = Database()
tables=['distance', 'speed']
for item in tables:
setattr(data, item, item)
which works, but isn't exactly what it should be.
Any ideas how to do it directly inside the class?

How to avoid duplication of class instances in Python?

What is a good way to avoid duplication of a class instance when it is created using the __init__() function.
This question is a result of this issue.
Context (using employee class example):
Lets say I have an employee class: __init__(self,name,dept)
I also have a method, employee.info(self) that prints out name and dept of any employee.
However a user could just add an employee by calling a=employee(args..). They could do it multiple times using the same instance variable a, but different employee names.
This will cause issues if they try to print a.info(), as each time a different employee name will be printed.
Is there a better way to do this? I know it is possible to have the __init__() "pass" and define a new method to create an instance.
Expect results:
>>Adam=employee('marketing')
>>Adam.info()
>>Adam works in marketing.
OR
>>a=employee('Adam','marketing')
>>a=employee('Mary','marketing')
>>Error: employee instance with identifier "a" already exists.
>>Use employee.update() method to modify existing record.
Is there a cleaner way of doing it? (as you might guess, I am still learning python).
Or is it good practice to write an explicit function (instead of a class method) to add new employees?
what you try is impossible, because in
a=employee('Adam','marketing')
a is not an object but a variable that points to the object employee('Adam','marketing').
When you do
a=employee('Mary','marketing')
you say to python that now, a must now not point to the object employee('Adam','marketing') but to the object employee('Mary','marketing'). And then, if you have no more variable to reference the object employee('Adam','marketing'), the garbage collector will destroy it.
You must consider that in python all is object, but not the variables that are only references to manipulate objects.
I have been racking my brains over the same problem and have finally managed to figure out a workaround :
Create a dictionary that stores the employee name and the related object like this :
total_emp_dict = {}
Add this inside the def __init__ of the class employee : total_emp_dict[name] = self. This will ensure to add each employee name as key and the object associated will be added as value.
Now create a new function outside & before the employee class is defined, let's call it create_new_emp. It will go like this :
#function to check and avoid duplicate assignment of instances
def create_new_emp(name, dept):
if name in total_emp_dict:
return total_emp_dict[name]
else:
return employee(name, dept)
When creating a any new employee, use this new function : a = create_new_emp("Adam", HR) instead of a = employee("Adam", HR)
Explanation : This function will ensure that duplicate assignment is not done. If "a" is already assigned to "Adam", this function will return object of "Adam" to "a", when called again. But if nothing is assigned to "a", then this function will handover to the attributes (name, dept) to employee class and create a new instance. This instance will then be assigned to "a".
I don't know if this is the best solution for this problem, but honestly this is the only solution I have found so far and it works great for me without much fuss / extra code space. Hope it works for you too! :)

Mongoose/ Mongo: why does $set auto-sort the data keys on update? [duplicate]

If I create an object like this:
var obj = {};
obj.prop1 = "Foo";
obj.prop2 = "Bar";
Will the resulting object always look like this?
{ prop1 : "Foo", prop2 : "Bar" }
That is, will the properties be in the same order that I added them?
The iteration order for objects follows a certain set of rules since ES2015, but it does not (always) follow the insertion order. Simply put, the iteration order is a combination of the insertion order for strings keys, and ascending order for number-like keys:
// key order: 1, foo, bar
const obj = { "foo": "foo", "1": "1", "bar": "bar" }
Using an array or a Map object can be a better way to achieve this. Map shares some similarities with Object and guarantees the keys to be iterated in order of insertion, without exception:
The keys in Map are ordered while keys added to object are not. Thus, when iterating over it, a Map object returns keys in order of insertion. (Note that in the ECMAScript 2015 spec objects do preserve creation order for string and Symbol keys, so traversal of an object with ie only string keys would yield keys in order of insertion)
As a note, properties order in objects weren’t guaranteed at all before ES2015. Definition of an Object from ECMAScript Third Edition (pdf):
4.3.3 Object
An object is a member of the
type Object. It is an unordered collection of properties each of which
contains a primitive value, object, or
function. A function stored in a
property of an object is called a
method.
YES (but not always insertion order).
Most Browsers iterate object properties as:
Positive integer keys in ascending order (and strings like "1" that parse as ints)
String keys, in insertion order (ES2015 guarantees this and all browsers comply)
Symbol names, in insertion order (ES2015 guarantees this and all browsers comply)
Some older browsers combine categories #1 and #2, iterating all keys in insertion order. If your keys might parse as integers, it's best not to rely on any specific iteration order.
Current Language Spec (since ES2015) insertion order is preserved, except in the case of keys that parse as positive integers (eg "7" or "99"), where behavior varies between browsers. For example, Chrome/V8 does not respect insertion order when the keys are parse as numeric.
Old Language Spec (before ES2015): Iteration order was technically undefined, but all major browsers complied with the ES2015 behavior.
Note that the ES2015 behavior was a good example of the language spec being driven by existing behavior, and not the other way round. To get a deeper sense of that backwards-compatibility mindset, see http://code.google.com/p/v8/issues/detail?id=164, a Chrome bug that covers in detail the design decisions behind Chrome's iteration order behavior.
Per one of the (rather opinionated) comments on that bug report:
Standards always follow implementations, that's where XHR came from, and Google does the same thing by implementing Gears and then embracing equivalent HTML5 functionality. The right fix is to have ECMA formally incorporate the de-facto standard behavior into the next rev of the spec.
Property order in normal Objects is a complex subject in JavaScript.
While in ES5 explicitly no order has been specified, ES2015 defined an order in certain cases, and successive changes to the specification since have increasingly defined the order (even, as of ES2020, the for-in loop's order). Given is the following object:
const o = Object.create(null, {
m: {value: function() {}, enumerable: true},
"2": {value: "2", enumerable: true},
"b": {value: "b", enumerable: true},
0: {value: 0, enumerable: true},
[Symbol()]: {value: "sym", enumerable: true},
"1": {value: "1", enumerable: true},
"a": {value: "a", enumerable: true},
});
This results in the following order (in certain cases):
Object {
0: 0,
1: "1",
2: "2",
b: "b",
a: "a",
m: function() {},
Symbol(): "sym"
}
The order for "own" (non-inherited) properties is:
Positive integer-like keys in ascending order
String keys in insertion order
Symbols in insertion order
Thus, there are three segments, which may alter the insertion order (as happened in the example). And positive integer-like keys don't stick to the insertion order at all.
In ES2015, only certain methods followed the order:
Object.assign
Object.defineProperties
Object.getOwnPropertyNames
Object.getOwnPropertySymbols
Reflect.ownKeys
JSON.parse
JSON.stringify
As of ES2020, all others do (some in specs between ES2015 and ES2020, others in ES2020), which includes:
Object.keys, Object.entries, Object.values, ...
for..in
The most difficult to nail down was for-in because, uniquely, it includes inherited properties. That was done (in all but edge cases) in ES2020. The following list from the linked (now completed) proposal provides the edge cases where the order is not specified:
Neither the object being iterated nor anything in its prototype chain is a proxy, typed array, module namespace object, or host exotic object.
Neither the object nor anything in its prototype chain has its prototype change during iteration.
Neither the object nor anything in its prototype chain has a property deleted during iteration.
Nothing in the object's prototype chain has a property added during iteration.
No property of the object or anything in its prototype chain has its enumerability change during iteration.
No non-enumerable property shadows an enumerable one.
Conclusion: Even in ES2015 you shouldn't rely on the property order of normal objects in JavaScript. It is prone to errors. If you need ordered named pairs, use Map instead, which purely uses insertion order. If you just need order, use an array or Set (which also uses purely insertion order).
At the time of writing, most browsers did return properties in the same order as they were inserted, but it was explicitly not guaranteed behaviour so shouldn't have been relied upon.
The ECMAScript specification used to say:
The mechanics and order of enumerating the properties ... is not specified.
However in ES2015 and later non-integer keys will be returned in insertion order.
This whole answer is in the context of spec compliance, not what any engine does at a particular moment or historically.
Generally, no
The actual question is very vague.
will the properties be in the same order that I added them
In what context?
The answer is: it depends on a number of factors. In general, no.
Sometimes, yes
Here is where you can count on property key order for plain Objects:
ES2015 compliant engine
Own properties
Object.getOwnPropertyNames(), Reflect.ownKeys(), Object.getOwnPropertySymbols(O)
In all cases these methods include non-enumerable property keys and order keys as specified by [[OwnPropertyKeys]] (see below). They differ in the type of key values they include (String and / or Symbol). In this context String includes integer values.
Object.getOwnPropertyNames(O)
Returns O's own String-keyed properties (property names).
Reflect.ownKeys(O)
Returns O's own String- and Symbol-keyed properties.
Object.getOwnPropertySymbols(O)
Returns O's own Symbol-keyed properties.
[[OwnPropertyKeys]]
The order is essentially: integer-like Strings in ascending order, non-integer-like Strings in creation order, Symbols in creation order. Depending which function invokes this, some of these types may not be included.
The specific language is that keys are returned in the following order:
... each own property key P of O [the object being iterated] that is an integer index, in ascending numeric index order
... each own property key P of O that is a String but is not an integer index, in property creation order
... each own property key P of O that is a Symbol, in property creation order
Map
If you're interested in ordered maps you should consider using the Map type introduced in ES2015 instead of plain Objects.
As of ES2015, property order is guaranteed for certain methods that iterate over properties. but not others. Unfortunately, the methods which are not guaranteed to have an order are generally the most often used:
Object.keys, Object.values, Object.entries
for..in loops
JSON.stringify
But, as of ES2020, property order for these previously untrustworthy methods will be guaranteed by the specification to be iterated over in the same deterministic manner as the others, due to to the finished proposal: for-in mechanics.
Just like with the methods which have a guaranteed iteration order (like Reflect.ownKeys and Object.getOwnPropertyNames), the previously-unspecified methods will also iterate in the following order:
Numeric array keys, in ascending numeric order
All other non-Symbol keys, in insertion order
Symbol keys, in insertion order
This is what pretty much every implementation does already (and has done for many years), but the new proposal has made it official.
Although the current specification leaves for..in iteration order "almost totally unspecified, real engines tend to be more consistent:"
The lack of specificity in ECMA-262 does not reflect reality. In discussion going back years, implementors have observed that there are some constraints on the behavior of for-in which anyone who wants to run code on the web needs to follow.
Because every implementation already iterates over properties predictably, it can be put into the specification without breaking backwards compatibility.
There are a few weird cases which implementations currently do not agree on, and in such cases, the resulting order will continue be unspecified. For property order to be guaranteed:
Neither the object being iterated nor anything in its prototype chain is a proxy, typed array, module namespace object, or host exotic object.
Neither the object nor anything in its prototype chain has its prototype change during iteration.
Neither the object nor anything in its prototype chain has a property deleted during iteration.
Nothing in the object's prototype chain has a property added during iteration.
No property of the object or anything in its prototype chain has its enumerability change during iteration.
No non-enumerable property shadows an enumerable one.
In modern browsers you can use the Map data structure instead of a object.
Developer mozilla > Map
A Map object can iterate its elements in insertion order...
In ES2015, it does, but not to what you might think
The order of keys in an object wasn't guaranteed until ES2015. It was implementation-defined.
However, in ES2015 in was specified. Like many things in JavaScript, this was done for compatibility purposes and generally reflected an existing unofficial standard among most JS engines (with you-know-who being an exception).
The order is defined in the spec, under the abstract operation OrdinaryOwnPropertyKeys, which underpins all methods of iterating over an object's own keys. Paraphrased, the order is as follows:
All integer index keys (stuff like "1123", "55", etc) in ascending numeric order.
All string keys which are not integer indices, in order of creation (oldest-first).
All symbol keys, in order of creation (oldest-first).
It's silly to say that the order is unreliable - it is reliable, it's just probably not what you want, and modern browsers implement this order correctly.
Some exceptions include methods of enumerating inherited keys, such as the for .. in loop. The for .. in loop doesn't guarantee order according to the specification.
As others have stated, you have no guarantee as to the order when you iterate over the properties of an object. If you need an ordered list of multiple fields I suggested creating an array of objects.
var myarr = [{somfield1: 'x', somefield2: 'y'},
{somfield1: 'a', somefield2: 'b'},
{somfield1: 'i', somefield2: 'j'}];
This way you can use a regular for loop and have the insert order. You could then use the Array sort method to sort this into a new array if needed.
Major Difference between Object and MAP with Example :
it's Order of iteration in loop, In Map it follows the order as it was set while creation whereas in OBJECT does not.
SEE:
OBJECT
const obj = {};
obj.prop1 = "Foo";
obj.prop2 = "Bar";
obj['1'] = "day";
console.log(obj)
**OUTPUT: {1: "day", prop1: "Foo", prop2: "Bar"}**
MAP
const myMap = new Map()
// setting the values
myMap.set("foo", "value associated with 'a string'")
myMap.set("Bar", 'value associated with keyObj')
myMap.set("1", 'value associated with keyFunc')
OUTPUT:
**1. ▶0: Array[2]
1. 0: "foo"
2. 1: "value associated with 'a string'"
2. ▶1: Array[2]
1. 0: "Bar"
2. 1: "value associated with keyObj"
3. ▶2: Array[2]
1. 0: "1"
2. 1: "value associated with keyFunc"**
Just found this out the hard way.
Using React with Redux, the state container of which's keys I want to traverse in order to generate children is refreshed everytime the store is changed (as per Redux's immutability concepts).
Thus, in order to take Object.keys(valueFromStore) I used Object.keys(valueFromStore).sort(), so that I at least now have an alphabetical order for the keys.
For a 100% fail-safe solution you could use nested objects and do something like this:
const obj = {};
obj.prop1 = {content: "Foo", index: 0};
obj.prop2 = {content: "Bar", index: 1};
for (let i = 0; i < Object.keys(obj).length; i++)
for (const prop in obj) {
if (obj[prop].index == i) {
console.log(obj[prop].content);
break;
}
}
From the JSON standard:
An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a string, number, boolean, null, object, or array.
(emphasis mine).
So, no you can't guarantee the order.

What is in the reduce function arguments in CouchDB?

I understand that the reduce function is supposed to somewhat combine the results of the map function but what exactly is passed to the reduce function?
function(keys, values){
// what's in keys?
// what's in values?
}
I tried to explore this in the Futon temporary view builder but all I got were reduce_overflow_errors. So I can't even print the keys or values arguments to try to understand what they look like.
Thanks for your help.
Edit:
My problem is the following. I'm using the temporary view builder of Futon.
I have a set of document representing text files (it's for a script I want to use to make translation of documents easier).
text_file:
id // the id of the text file is its path on the file system
I also have some documents that represent text fragments appearing in the said files, and their position in each file.
text_fragment:
id
file_id // correspond to a text_file document
position
I'd like to get for each text_file, a list of the text fragments that appear in the said file.
Update
Note on JavaScript API change: Prior to Tue, 20 May 2008 (Subversion revision r658405) the function to emit a row to the map index, was named "map". It has now been changed to "emit".
That's the reason why there is mapused instead of emitit was renamed. Sorry I corrected my code to be valid in the recent version of CouchDB.
Edit
I think what you are looking for is a has-many relationship or a join in sql db language. Here is a blog article by Christopher Lenz that describes exactly what your options are for this kind of scenario in CouchDB.
In the last part there is a technique described that you can use for the list you want.
You need a map function of the following format
function(doc) {
if (doc.type == "text_file") {
emit([doc._id, 0], doc);
} else if (doc.type == "text_fragment") {
emit([doc.file_id, 1], doc);
}
}
Now you can query the view in the following way:
my_view?startkey=["text_file_id"]&endkey;=["text_file_id", 2]
This gives you a list of the form
text_file
text_fragement_1
text_fragement_2
..
Old Answer
Directly from the CouchDB Wiki
function (key, values, rereduce) {
return sum(values);
}
Reduce functions are passed three arguments in the order key, values and rereduce
Reduce functions must handle two cases:
When rereduce is false:
key will be an array whose elements are arrays of the form [key,id], where key is a key emitted by the map function and id is that of the document from which the key was generated.
values will be an array of the values emitted for the respective elements in keys
i.e. reduce([ [key1,id1], [key2,id2], [key3,id3] ], [value1,value2,value3], false)
When rereduce is true:
key will be null
values will be an array of values returned by previous calls to the reduce function
i.e. reduce(null, [intermediate1,intermediate2,intermediate3], true)
Reduce functions should return a single value, suitable for both the value field of the final view and as a member of the values array passed to the reduce function.

Resources