Underscore.js - without and difference methods trouble - javascript

I am trying to use the _.without and _.difference methods in the underscore.js library with no luck.
Here is some code.
var someIds = _.pluck(parsedID1, 'id');
var otherIds = _.pluck(parsedID2, 'id);
Here is where the trouble starts, I want to remove all of the otherIds out of the someId's list. So I have two options according to the website, either I can use _.difference || _.without. I use them like so...
var newArray = _.without(_.toArray(someIds), _.toArray(otherIds));
I have also tried to do this with _.difference as well, but I cant seem to get the methods to do anything other than return a copy of the first argument into the function. I have also tried passing the arguments into the functions without using the _.toArray() but the same thing happens.Has anyone ever encountered this error before?
EDIT:
I have tried the way as proposed below. I will give some more code in hopes of fixing this.
The arrays that I am passing in as arguments are in the following format.
var array = ['100004191488120', '100004191488321'];
When I pass into the _.difference I do as follows:
var newArray = _.difference(someIds, otherIds);
If someIds length is 657 and otherIds is 57 I should be getting a result of 600 Id's. Instead I get a result of whatever the length of the first argument is, being 657.
EDIT 2: Solved
I figured out what the problem was, after all that frustration the problem lied with the second argument to difference I was passing in.
I was doing a db query and getting back a list that looked like the following.
[{ _id: 514721152222111116666777, facebook: { id: '123456789' } },
{ _id: 514721152222111116666778, facebook: { id: '12345678' } },]
After I received those results I wanted to get the facebook id so I did the following,
var array = _.pluck(users, 'facebook.id');
Thats were the problem was, that pluck was sending me back a list of undefined. Instead I had to do 2 plucks before instead of one, like the following.
var temp = _.pluck(users, 'facebook');
var arrayId = _.pluck(temp, 'id');
Thanks #ZenMaster for dropping the knowledge on the difference between _.without && _.difference. Your answer was correct, was pretty brain-dead after a binder and didn't see the obvious.

You don't need an _.toArray on the first argument of the without function
The second (and more) arguments to the without is not an array - it's a "list" of values.
The proper call would be:
var newArray = _.without(['1', '2', '3'], '1', '3');
which would result in:
['2']
In your case, you'd have to use _.difference as can be seen on JSFiddle here.
Here is the code:
var parsedID1 = [{id: '1', name: 'name1'}, {id: '2', name: 'name2'}];
var parsedID2 = [{id: '1', name: 'name1'}, {id: '3', name: 'name3'}];
var someIds = _.pluck(parsedID1, 'id');
var otherIds = _.pluck(parsedID2, 'id');
console.log(someIds, otherIds);
var newArray = _.difference(someIds, otherIds);
console.log(newArray);

Related

Extracting unique values from an array of objects where value is a nested object in JavaScript

Let's say I've got the following array of objects in JavaScript:
const requests = [
{
id: 1,
person: {
id: 1
}
},
{
id: 2,
person: {
id: 1
}
},
{
id: 3,
person: {
id: 2
}
},
{
id: 4,
person: {
id: 3
}
},
{
id: 5,
person: {
id: 2
}
}
]
And what I've written below will go over each item in the array, and then create a new array containing just the person object.
const requestsPeopleIds = []
for (const request of requests) {
requestsPeopleIds.push(request.person.id)
}
I then take that new array and create another new array using Set to remove the duplicate ids:
const uniquePeopleIds = Array.from(new Set(requestsPeopleIds))
The final result is as I'd expect:
console.log(uniquePeopleIds) // [1, 2, 3]
where these are the unique ids of the people who made a request. So out of the 5 requests, these were made by 3 people.
There must be a more efficient way of doing this, so I'm reaching out to you stack overflow JS gurus.
Thanks in advance.
I think you got the basics. Here's a way to tighten the code:
var ids = new Set;
requests.forEach(i => ids.add(i.person.id));
You could also do this with map method and spread syntax ....
const requests = [{"id":1,"person":{"id":1}},{"id":2,"person":{"id":1}},{"id":3,"person":{"id":2}},{"id":4,"person":{"id":3}},{"id":5,"person":{"id":2}}]
const result = [...new Set(requests.map(({ person: { id }}) => id))]
console.log(result)
You can do it by making an object by the person's id as a key and get the keys of the object.
const requests = [{"id":1,"person":{"id":1}},{"id":2,"person":{"id":1}},{"id":3,"person":{"id":2}},{"id":4,"person":{"id":3}},{"id":5,"person":{"id":2}}]
// Take an empty object
const uniques = {};
// Iterate through the requests array and make person's id as a
// key of the object and put any value at this index (here I put 1).
requests.forEach(request => (uniques[request.person.id] = 1));
// Finally get the keys of the unique object.
console.log(Object.keys(uniques));
I've done some research and have inferred some interesting facts:
It looks like when we have very various data and larger array, then Set collection shows not best results. Set is very optimized collection, however, in my view, it should always check whether element is already added into Set. And this checking will take O(n) complexity. But we can use simple JavaScript object. Checking whether object contains key is O(1). So object will have huge advantage over Set.
foreach arrow function is very convenient, however, simple for loop is faster.
Adding console.log makes Set the most fastest solution, however, without console.log, the most fastest solution is combination of for loop and object.
So the most performant code without console.log() looks like this:
const hashMap = {};
const uniques = [];
for (let index = 0; index < requests.length; index++) {
if (!hashMap.hasOwnProperty(requests[index].person.id)){
hashMap[requests[index].person.id] = 1;
uniques.push(requests[index].person.id);
}
}
However, the most performant code with console.log() looks like this(I cannot understand the reason why it happens. It would be really great to know why it happens):
var ids = new Set;
requests.forEach(i => ids.add(i.person.id));
console.log(ids)
Tests:
with console.log
without console.log

How to add new elements to an array without overwriting the first one?

I'm trying to add new elements to an Array but it keeps overwriting it the first element, i'm not sure if i'm doing it correctly, but this is my code:
//name and age contains value from a NgModel
this.data = [
{ "name": this.name, "age": this.age },
];
//Adds them to a new array
this.nArray = [];
this.nArray.push(this.data);
Use concat when you want to merge two arrays.
const nArray = [];
const arr = nArray.concat(this.data);
You can now use the new merged array for your purpose
As it is, you are pushing an array to an empty array. So, there is nothing like overriding here. However, assuming this.nArray is filled with some elements already, you should use the spread syntax for concatenating two arrays like:
this.nArray.push(...this.data);
push method is ok for you. It will add elements at the end of the array. If you have data already setted in your array, then remove this.nArray = [] because this is creating a new empty array, deleting all previous data stored in nArray variable. In any case, if you want to add elements at the beginning try unshift: this.nArray.unshift(this.data);.
If you push data inside nArray you will get an array of array of objects. Maybe you are looking to add only the elements in data and not the whole array. Use concat method for that.
this.nArray.push(this.nArray.concat(data));
Or a shorten syntax using spread operator ...:
this.nArray.push(...data);
NOTE:
I'd recommend you to use const for your array definition and remove the blank assignment of [] in nArray. Also, instead of using concat, use the spread operators with the push method.
Another way to add/insert an element into an array is to use the .splice() method.
With .splice() you can insert a new element at any given index, either overwriting what is currently in that index number, or inserting within, with no overwriting.
Example:
let secretMessage = [ 'Programming', 'is', 'not', 'about', 'what', 'you', 'get',
'easily', 'the', 'first', 'time,', 'it', 'is', 'about', 'what', 'you', 'can',
'figure', 'out.', '-2015,', 'Chris', 'Pine,', 'Learn', 'to', 'Program' ]
read: 'Programming is not about what you get easily the first time, it is about what you can figure out. -2015, Chris Pine, Learn to Program'
secretMessage.splice(6, 5, 'know,');
console.log(secretMessage.join(' '); //log array elements to console, but join them
//with a space (makes it more human legible)
read: 'Programming is not about what you know, it is about what you can figure out. -2015, Chris Pine, Learn to Program'
In this example, at index (position) 6 (starting from 0) we replace the 5 elements from index 6 with the third argument - 'know,'.
If you wanted to insert an element without replacing another, use the same .splice() method but for the second argument, type 0.
Example:
let favDrink = ['I', 'like', 'milkshake.']
favDrink.splice(2, 0, 'banana'); //at index position 2, insert 'banana'.
//***Does not replace 'milkshake'***
console.log(favDrink.join(' ');
read: 'I like banana milkshake.'
Source:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
You know what? You might be reinitializing your array every time.
Try something like this:
// create your new array
this.nArray = [];
// other code
// loop, etc
$.each(row, function(index, data) {
this.data = [
{ "name": this.name, "age": this.age },
];
// now add this element to your array:
this.nArray.push(this.data);
};
Adding the Object in the array...!
Write in this format
let data = [];
data[data.length] = {name:"Aarti",age:22}
data[data.length] = {name:"Saurav",age:23}
console.log(data);

Insert objects without matching column name

This is probably a silly question, but I am new to node and postgresql, so I am struggling.
I am trying to use pgp.helpers.insert to insert multiple objects into the database, as the example bellow:
users = [{mycolumn:{name: 'John', age:23}}, {mycolumn:{name: 'Mike', age: 30}}];
query = pgp.helpers.insert(users, ['mycolumn:json'], 'mytable');
// insert into "mytable"("mycolumn") values('{"name":"John","age":23}'),('{"name":"Mike","age":30}')
The code above inserts into mytable 2 rows with mycolumn as a jsonb.
But I am trying to insert straight into mycolumn the values inside an array of objects, without wrapping my original object, such as:
users = [{name: 'John', age:23}, {name: 'Mike', age: 30}];
query = pgp.helpers.insert(users, ['mycolumn:json'], 'mytable');
// Error: Property 'mycolumn' doesn't exist.
Of course it doesn't work, since the object doesn't contain a mycolumn attribute. But I think it is not elegant to iterate in my array wrapping the original object with the column name, specially since I am working with millions of rows (working in batches, of course).
Thanks in advance.
You can use the following definition for your column, as per the Column syntax:
{
name: 'mycolumn',
init: c => c.source // use the source object itself
}
i.e.
const cs = new pgp.helpers.ColumnSet([
{
name: 'mycolumn',
init: c => c.source
}
], {table: 'mytable'});
and then use it:
const query = pgp.helpers.insert(users, cs);
Note that we are not specifying the modifier - mod: ':json', because we are returning an object from init, and objects are formatted as JSON by default.

Learning to programming JavaScript, but I'm stuck

Yesterday I started learning JavaScript. I am using the system Codecademy, but I'm stuck. When I say "stuck", I mean I have assignment with which I cannot see what is wrong.
The assignment is:
Create an array, myArray. Its first element should be a number, its second should be a boolean, its third should be a string, and its fourth should be...an object! You can add as many elements of any type as you like after these first four.
This is the code I made:
var myObj = {
name: 'Hansen'
};
var myArray = [12,true, "Steen" ,myObj.name];
The error:
Oops, try again.
Is the fourth element of myArray an object?
Hope you can help me.
The problem with your fourth element is you are passing a string because myObj.name is defined as Hansen. Pass the object instead:
var myArray = [12,true, "Steen" ,myObj];
I don't know that site, but you can do:
var myArray = [
12,
true,
"Steen",
{name: 'Hansen'}
];
What you are passing to the array is the value of the name property of your object instead of the object itself.
Your passing in the name property instead of the object for the fourth array parameter as you probably already know from the other anwers.
As your learning here are a few ways to do exactly the same thing as your accomplishing here.
Your way corrected:
var myObj = {
name: 'Hansen'
};
var myArray = [12, true, "Steen", myObj];
Other ways:
// Method 1
var myArray = [12, true, "Steen", {name: 'Hansen'}];
// Method 2
var myObj = new Object();
myObj.name = "Hansen";
var myArray = new Array(12, true, "Steen", myObj);
// Method 3
var myObj = {};
myObj['name'] = 'Hansen'
var myArray = [
12, true, 'Steen', myObj
]
Each method shows a few different ways to do the same thing, you can mix and match the equivalent parts of code to get the same job done. It's basically inter changing between the normal JavaScript syntax and object literal syntax.

Working with Java Script and multidimensional arrays

I am currently working on a website type project and I am new to JavaScript. So I have been having troubles with some parts of the syntax. Basically I am trying to print the 'id' and 'value' in the nested array arr.
var myArray = new Array({id:'1', value:'een', arr: new Array({id:'10', value:'een'})};
var obj = myArray[0];
document.write(obj.id);
this will print the id 1 but im not sure how to access id 10.
Also if there is an easier way to do this let me know please!
Firstly, don't use the new Array constructor. Just define an array literal [...]. So your myArray will look like:
var myArray = [{id:'1', value:'een', arr: [{id:'10', value:'een'}]}];
To get to the id of 10, you need to access myArray[0].arr[0].id;.
Proper reference would be:
obj.arr[0].id
PS: google chrome developer console is a goot playground for testing javascript object dereefrecing
You can't without iterating over the array.
If order does not matter, use an object instead:
var myObject = {
1: {id:'1', value:'een'},
10: {id:'10', value:'een'}
};
var obj = myArray[10];
document.write(obj.id);
In case the nesting in your array is intended, here's what you want:
var obj = myArray[0].arr[0];
Demo:
> var myArray = new Array({id:'1', value:'een', arr: new Array({id:'10', value:'een'})});
> myArray[0].arr[0]
{ id: '10', value: 'een' }
I would for get arrays why not create your own object ?
http://www.w3schools.com/js/js_objects.asp

Categories

Resources