Order changed after distinct() : RethinkDb Javascript - javascript

I am working with the Reql, the problem i am facing is that i need to filter the same plucked values in correct order.
After pluck and distinct() apply, value are correct but not in correct order, their order lost.
Sample Query
r.db('DB').table("heroes").orderBy('createdAt')
.pluck({'loc':['coordinates']})
.distinct()
Can anyone help me to modify the query, so that it return data in correct order.
Thanks for your time.

After looking for another workaround i posted question here (thanks to #trincot) to get work done in javascript instead to handle duplicate array of lat longs, by duplicating solution of this sample array. Getting distinct result and the order is maintained.
var array = [
{ person: { amount: [1,1] } },
{ person: { amount: [1,1] } },
{ person: { amount: [2,1] } },
{ person: { amount: [1,2] } },
{ person: { amount: [1,2] } }
];
var result = [...new Map(array.map( o => [JSON.stringify(o), o])).values()];
console.log(result);
In case of anyone who might get help.Cheers.

Related

Group values keys based for each other value key

Sorry for bad title, I don't really know how to phrase this and this might be trivial problem ...
The data that comes from the array looks like this, each name can have an indefinite amount of sequence, what I want to do is group them by name and put each sequence in an array
[
{
name: 'Mike',
sequence: 'AAAA',
},
{
name: 'Bob',
sequence: 'ABAB',
},
{
name: 'Bob',
sequence: 'AAAB',
},
{
name: 'Marvin',
sequence: 'AAAA',
},
{
name: 'Marvin',
sequence: 'AABA',
},
{
name: 'Marvin',
sequence: 'BBBB',
},
]
What I am looking to return for each name by using console.log(name, array) for example would be something like this
Mike ["AAAA"]
Bob ["ABAB","AAAB"]
Marvin ["AAAA","AABA","BBBB"]
Thank you very much!
As mentioned in the comments, it seems you have tried some ways to solve the problem.
You can try following solution
Use Array.reduce to convert your array into an object with keys as name and value as array of sequences
In the reduce function, check whether the name exist in the resultant object. If it exists, concat the sequence to it (using spread syntax) else add a new entry with an array with sequence.
let input = [{name:'Mike',sequence:'AAAA',},{name:'Bob',sequence:'ABAB',},{name:'Bob',sequence:'AAAB',},{name:'Marvin',sequence:'AAAA',},{name:'Marvin',sequence:'AABA',},{name:'Marvin',sequence:'BBBB',}];
let result = input.reduce((a, {name, sequence}) => Object.assign(a, {[name] : a[name] ? [...a[name], sequence]: [sequence]}), {});
console.log(result);
inputArray.reduce((acc,{name,sequence}) => {
let obj = acc.find(a => a.name === name);
obj ? obj.sequence.push(sequence)
: acc.push({name,sequence:[sequence]});
return acc;
}, [])

Create an object or associative array with elements of an existing array and the result of a callout for each element

This is in the context of a node express route. I receive a get request with a query param that is a list of IDs. Now I need to make a call-out for each ID and store the result of the callout in an array or object. Each element of the first array (containing the IDs) need to be mapped to its corresponding result from the call-out. I don't have a way to modify the endpoint that I'm hitting from this route so I have to make single calls for each ID. I've done some research and so far I have a mixture of code and sudo code like this:
const ids = req.query.ids;
const idMembers = Promise.all(ids.map(async id => {
// here I'd like to create a single object or associative array
[ id: await callout(id); ]
}));
When all promises resolved I need the final result of idMembers to be like: (The response will be an object with nested arrays and objects I've just simplified it for this post but I need to grab that from the res.payload)
{
'211405': { name: 'name1', email: 'email1#test.co' },
'441120': { name: 'name2', email: 'email2#test.co' },
'105020': { name: 'name3', email: 'email4#test.co' }
}
Oh and of course I need to handle the callout and the promise failures and that's when my lack of experience with javascript becomes a real issue. I appreciate your help in advance!!
Some extra thought I'm having is that I'd have to map the results of the resolved promises to their id and then in a separate iteration I can then create my final array/object that maps the ids to the actual payloads that contain the object. This is still not answering any of my questions though. I'm just trying to provide as much information as I've gathered and thought of.
Promise.all returns an array of results (one item per each promise).
Having this temporary structure it is possible to build the needed object.
const arrayOfMembers = Promise.all(ids.map(async id => {
// ...
return { id, value: await callout(id) } // short syntax for { id: id, value: ... } (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer)
}));
// arrayOfMembers = [
// { id: 211405, value: { name: 'name1', email: 'email1#test.co' } },
// ...
// ]
In pure JS it can be done with for loop or .forEach() call to iterate:
const res = {};
arrayOfMembers.forEach(el => {
const { id, value } = el;
res[el] = value;
});
or by using a single reduce() call
const res = arrayOfMembers.reduce((accumulator, el) => {
const { id, value } = el;
return { ...accumulator, [id]: value };
}, {});
in both cases res will be:
// res = {
// '211405': { name: 'name1', email: 'email1#test.co' },
// ...
// }
P.S.
There is a handy library called lodash. It has tons of small methods for data manipulation.
For example, _.fromPairs() can build an object from [[key1, value1], [key2, value2]] pairs.
As you mentioned you have lodash, so I think the following should work:
const arrayOfKeyValuePairs = Promise.all(ids.map(async id => {
// ...
return [ id, await callout(id) ] // array here so it matches what fromPairs needs
}));
const res = _.fromPairs(arrayOfKeyValuePairs);

Removing duplicates elements with conditionality

I have an array of objects that look like this:
[
{ project: "test1", date: "8/14/2018" },
{ project: "test1", date: "8/15/2018" },
{ project: "test2", date: "8/14/2018" }
]
I want to remove duplicate objects based on the project name, BUT, keep the one with the most recent date.
So my final array would like this:
[
{ project: "test1", date: "8/15/2018" },
{ project: "test2", date: "8/14/2018" }
]
I've come up with a disgruntled recursive solution that I'm unhappy with.
Looking for suggestions on a painless way to do this.
The approach I generally take for problems like this is to maintain a "dictionary" object to track uniqueness while iterating through, then extract the final result from that result. reduce is the go-to tool for creating one value from multiple values:
const dict = objects.reduce((result, item) => {
const currentForProject = result[item.project];
const isMostRecent =
!currentForProject
|| new Date(item.date) > new Date(currentForProject.date);
if (isMostRecent) {
result[item.project] = item;
}
return result;
}, {});
const mostRecents = Object.values(dict);
I will propose the general algorithm to solve your task but the implementation is up to you.
1) sort the array based on date field;
2) create an empty Set for storing project names and empty array for the result;
3) iterate over the sorted array and check:
3.1) if the Set does not contain current project name, then:
3.2) add the project name to the Set and add current item to your result
array;

query an array of objects and return a single object - mongodb

I'm having some trouble searching an array I have in my model which currently contains dummy posts.
My posts array looks like this
posts: [
{
image: <filename>,
comments: [],
joined: <number>,
}
]
The posts array atm holds about 10 objects. I need a way to query this array and return a single object. I already tried the answers given on other similar questions, but they all return the whole user which is not what I want.
I tried this:
model
.find(
{ $match : { "posts.image": req.params.image } },
{ $unwind : "$posts" },
{ $match : { "posts.image": req.params.image } }
)
This also returns the whole object including the password, username, etc. I also tried $elemMatch, and no luck.
I'm only expecting it to return one object (not multiple objects) since ill be querying the array with req.params.
Unsure
Not entirely certain if this is what you are asking for, but a way to get a single property value of an array would be done this way
If I am misunderstood please clarify what you are after and I will amend my answer.
var posts = [{
image: "x.jpg",
comments: [],
joined: 12
},
{
image: "x1.jpg",
comments: [],
joined: 121
},
{
image: "ax.jpg",
comments: [],
joined: 2
}
];
for (a = 0; a < posts.length; a++){
console.log(posts[a].image);
}

Manipulating objects in an array

I am new to JavaScript and been struggling to combine objects in the same array.
Here is what I have:
var testList = [{
'taskList1': 'task1 for taskList1',
},
{
'taskList1': 'task2 for taskList1',
},
{
'taskList2': 'task1 for taskList2'
},
{
'taskList2': 'task2 for taskList2'
}]
The array below is what I really want to get from above:
var testList = [{
'taskList1': 'task1 for taskList1',
'taskList2': 'task1 for taskList2'
},
{
'taskList1': 'task2 for taskList1',
'taskList2': 'task2 for taskList2'
}]
Could anyone please help me to transform my current array into the one above?
Thank you in advance.
Your data structure is quite inefficient in this case. I'd suggest to make it better by having the same array of objects, but each object should contain itemName and belongsTo as a reference to any collection (in your case - a taskList) you may pass there.
Here's a solution to your problem with a more flexible data structure on Codepen - https://codepen.io/Inlesco/pen/dReYgd
I've also added the restructured array of tasks below as an example that's used in the Codepen above.
var testList = [{
item: 'task1',
belongsTo: 'taskList1'
},
{
item: 'task2',
belongsTo: 'taskList1'
},
{
item: 'task1',
belongsTo: 'taskList2'
},
{
item: 'task2',
belongsTo: 'taskList2'
}]
There are many ways to approach this problem. I've just added probably the simplest one.
You can use a for statement to regroup objects with the same taskList ID in one object.
And of course your need to use the right conditions for that.
But the best way is as #Denialos said, to modify your data structure.
Per my comments above to the question, your desired data structure appears to be inverted, or "inside out". Given a list of items, and a set of tasks for each item, I would expect the outer element to be the list, and the inner element to be the set of tasks.
Given that, given your (current) input data I would use:
function restructure(taskList) {
var result = {};
for (var i = 0, n = taskList.length; i < n; ++i) {
// read current item
var item = taskList[i];
var key = Object.keys(item)[0];
var value = item[key];
// update the output
result[key] = result[key] || [];
result[key].push(value);
}
return result;
}
with resulting output:
{
taskList1: [ 'task1 for taskList1', 'task2 for taskList1' ],
taskList2: [ 'task1 for taskList2', 'task2 for taskList2' ]
}
That said, your input data model is also somewhat malformed, with each array element having an unknown key. You should look at what's actually producing that data and fix that if possible.

Categories

Resources