Apply change record of property to another similar property - javascript

Is it possible to apply the changes provided by an observer to another object (similar object as the one observed) ?
E.g:
properties: {
boardBucket: {
type: Object,
value: {
items: [],
currentBoardId: 1
}
},
remoteBoardBucket: { // let's assume this is on another client
type: Object,
value: {
items: [],
currentBoardId: 1
}
}
},
observers: [
"_boardBucketChanged(boardBucket.*)"
],
_boardBucketChanged: function(changeRecord) {
// `applyChanges()` doesn't exist but can it be done?
this.remoteBoardBucket.applyChanges(changeRecord);
}
Why I'm asking this:
I'm building a collaborative editor where both parties manipulate their own boardBucket, adding/removing items(boards) to it and adding/removing items in those boards (boardBucket.items[2].boardItems is an array for each board that holds items in that board).
The clients communicate via web-sockets between them and I'd like to see if it's possible to send only the changeRecord through the sockets and have it applied on the other-client's boardBucket.
This will speed up things significantly as it negates the need to send the whole boardBucket back and forth (I'm not really doing this but for the sake of the question I'm putting it out here)
An important note here is that I'm observing nested arrays as well. While board.items is an array which holds the boards, each board also holds another array called boardItems which holds the items in those boards. Therefore there is an arbitrary number of levels of depth of changes I'm observing here.

Related

Delete element from a list, with multiple lists to check -- what's a good way to implement?

I created state within App.js for a single page application (kanban board)
Within the state i have three key values with arrays and one other key value:
this.state = {
currentItem: { text: '' },
toDoListItems: [
{ text: 'hello world' }
],
inProgressListItems: [],
doneListItems: []
}
Currently my implementation of use cases like delete a task from any board, is implemented by passing the name of the list item.
ie. {() => this.deleteItem(item, "toDoListItems")}
How should i make my code more extensible? I was thinking first, I should place all the lists within an object within state. But is it good/bad practice to manually iterate and which array contains the element that I'm looking for? It feels like if i were to do that, I'm making redundant checks.

Reading/writing nested data in a Firebase Database (web)

This seemingly simple question is surely a duplicate of many, so I apologize for that. Won't be offended when it's marked as such... But I have yet to find a clear, straight forward and modern answer that seems to work as I'd expect.
Given "Item One", how can I return the "subItems" array for the object that matches that title?
Additionally, how do I push new subitems to that array (if there's some different way I should target that array when writing rather than reading)
And the context of this is "items" is the top-level db.ref('items')
To find an item by a property, you need to run a query that orders and filters on that property. So in your case:
var ref = firebase.database().ref("items");
var query = ref.orderByChild("title").equalTo("Item One");
query.once("value", function(snapshot) {
snapshot.forEach(function(item) {
console.log(item.key); // -L8...EMj7P
console.log(item.child("subItems").val()); // logs the sub items
// console.log(item.ref.child("subItems").push().set(...)); // adds a sub item
});
});
Note that nesting data types is an anti-pattern in the Firebase Database, since it typically leads to problems later on. A more idiomatic approach is to have two top-level lists (e.g. items and subItems) that then use the same keys:
items: {
-L8...EMj7P: {
title: "Item One"
}
},
subItems: {
-L8...EMj7P: {
...
}
}

How to optimize performance of searching in two array of object

There are two array of objects one from database and one from csv. I required to compare both array object by their relative properties of Phones and emails and find duplicate array among them. Due to odd database object structure I required to compare both array with Javascript. I wanted to know what is the best algorithm and best way of compare and find duplicates?
I explain simple calculations.
There are 5000 contacts in my database and user may upload another 3000 contacts from csv. Everytime we requires to find duplicate contacts from database and if they find then it may overwrite and rest should be insert. If I compare contact row by row then it may loop 5000 database contacts x 3000 csv contacts = 15000000 time traverse.
This is my present scenario I face due to this system goes stuck. I require some efficient solution of this issue.
I develop the stuff in NodeJS, RethinkDB.
Database object structure exactly represent like that way and it may duplicate entry of emails and phones in other contacts also.
[{
id: 2349287349082734,
name: "ABC",
phones: [
{
id: 2234234,
flag: true,
value: 982389679823
},
{
id: 65234234,
flag: false,
value: 2979023423
}
],
emails: [
{
id: 22346234,
flag: true,
value: "test#domain.com"
},
{
id: 609834234,
flag: false,
value: "test2#domain.com"
}
]
}]
Please review fiddle code, if you want: https://jsfiddle.net/dipakchavda2912/eua1truj/
I have already did indexing. The problem is looking very easy and known in first sight but when we talk about concurrency it is really very critical and CPU intensive.
If understand the question you can use the lodash method differenceWith
let csvContacts = [] //fill it with your values;
let databaseContacts = .... //from your database
let diffArray = [] //the non duplicated object;
const l = require("lodash");
diffArray = l.differenceWith(csvContact,
databaseContacts,
(firstValue,secValue)=>firstValue.email == secValue.email

MongoDB - Query conundrum - Document refs or subdocument

I've run into a bit of an issue with some data that I'm storing in my MongoDB (Note: I'm using mongoose as an ODM). I have two schemas:
mongoose.model('Buyer',{
credit: Number,
})
and
mongoose.model('Item',{
bid: Number,
location: { type: [Number], index: '2d' }
})
Buyer/Item will have a parent/child association, with a one-to-many relationship. I know that I can set up Items to be embedded subdocs to the Buyer document or I can create two separate documents with object id references to each other.
The problem I am facing is that I need to query Items where it's bid is lower than Buyer's credit but also where location is near a certain geo coordinate.
To satisfy the first criteria, it seems I should embed Items as a subdoc so that I can compare the two numbers. But, in order to compare locations with a geoNear query, it seems it would be better to separate the documents, otherwise, I can't perform geoNear on each subdocument.
Is there any way that I can perform both tasks on this data? If so, how should I structure my data? If not, is there a way that I can perform one query and then a second query on the result from the first query?
Thanks for your help!
There is another option (besides embedding and normalizing) for storing hierarchies in mongodb, that is storing them as tree structures. In this case you would store Buyers and Items in separate documents but in the same collection. Each Item document would need a field pointing to its Buyer (parent) document, and each Buyer document's parent field would be set to null. The docs I linked to explain several implementations you could choose from.
If your items are stored in two separate collections than the best option will be write your own function and call it using mongoose.connection.db.eval('some code...');. In such case you can execute your advanced logic on the server side.
You can write something like this:
var allNearItems = db.Items.find(
{ location: {
$near: {
$geometry: {
type: "Point" ,
coordinates: [ <longitude> , <latitude> ]
},
$maxDistance: 100
}
}
});
var res = [];
allNearItems.forEach(function(item){
var buyer = db.Buyers.find({ id: item.buyerId })[0];
if (!buyer) continue;
if (item.bid < buyer.credit) {
res.push(item.id);
}
});
return res;
After evaluation (place it in mongoose.connection.db.eval("...") call) you will get the array of item id`s.
Use it with cautions. If your allNearItems array will be too large or you will query it very often you can face the performance problems. MongoDB team actually has deprecated direct js code execution but it is still available on current stable release.

How to optimize accessing cost of nested objects in JavaScript?

I am trying to optimize accessing cost of nested objects. I have the following structure (example):
Now I want to access data but the problem is I need to keep on adding loops where every I got nested data. That means if I want to access racks I need to itterate 3 for loops like
var jsonObj=[{
"shelfs": [
{
"Shelf1": [
{
"Racks": [
{
"Rack1": [
{
"Book1": "Value"
}
]
},
{
"Rack2": [
{
"Book1": "Value"
}
]
}
]
}
]
},
{
"Shelf2": [
{
"Racks": [
{
"Rack1": [
{
"Book1": "Value"
}
]
},
{
"Rack2": [
{
"Book1": "Value"
}
]
}
]
}
]
}
]
}];
for(var i=0;i<jsonObj.length;i++)
{
var shelfs=jsonObj[i];
var key=Object.keys(shelfs)[0];
//var shelfs=arr[arr[0].key];
//alert(JSON.stringify(shelfs[key]));//shelfs));
for(var j=0;j<shelfs[key].length;j++)
{
var shelfdetails=shelfs[key][j];
var skeys=Object.keys(shelfdetails);
for(var k=0;k<skeys.length;k++)
{
var racks=shelfdetails[skeys[k]];
alert(JSON.stringify(racks));
}
}
}
Here to access racks information I put 3 nested for loops but eventually it is increasing the time complexity. Please can anybody suggest me better data structure or method to access nested JavaScript objects with low time complexity?
You have n books that you want to display in your UI. It will take n display operations to display n books. It does not matter that they are in nested loops, the total number of display operations is still n. There is no optimization you can perform to reduce the number of display operations you need to perform.
Even if you were to flatten your data structure in to a single flat array of books the number of display operations would still be n.
I am trying to optimize accessing cost of nested objects.
Do you mean the CPU cost, the storage cost, or the code complexity cost? The three have quite different implications. Since you go on to say
I need to keep on adding loops whereever I got nested data.
I am going to assume that you are most interested in code complexity. In that case, consider the following flatter data structure, which might be easier to loop through, to filter, to sort, to group, and to otherwise process using utility libraries such as underscore.
[
{ shelf: 'Shelf1', rack: 'Rack1', book: 'Book1', value: "Value"},
{ shelf: 'Shelf1', rack: 'Rack2', book: 'Book1', value: "Value"},
{ shelf: 'Shelf2', rack: 'Rack1', book: 'Book1', value: "Value"},
{ shelf: 'Shelf2', rack: 'Rack2', book: 'Book1', value: "Value"}
]
Abstractly speaking, each "Book1": "Value" item has associated with it a shelf and a rack. In your suggested data structure, this "association" is represented by "belonging to" relationships, where it belongs to an array which is the value of a property whose name specifies the shelf or rack. In the above flatter structure, the associations are instead specified explicitly by giving them as properties.
With the flatter structure, if for some reason you wanted to create a data object with keys giving the shelf and values giving an array of objects on that shelf, in Underscore that is as easy as
_.groupBy(obj, 'shelf')
So all else being equal it seems that the flatter data structure is a more flexible way to represent the data, and you can derive other things you need from it more easily.
Another way to look at it is that currently in order to find the sets of relationships of shelves, racks, and books, you need to iterate through three levels of nested arrays, whereas in the flatter structure the relationships are represented more directly.
Performance, either CPU-wise or space-wise, is rarely going to be a reason to choose one structure over another, unless you are dealing with a huge amount of data. Otherwise, the difference in performance is likely to measured in milliseconds or microseconds, or a few K of storage. You should choose the structure that allows you to represent your algorithms in a fashion which is concise and provably correct. If you intend to handle hundreds of thousands of objects, then in that case yes, you would want to design custom structures optimized for time or space.

Categories