How to make a variable using keys from literal object, javascript - javascript

In an exercise, I have to make a variable called "fullAddress" that contains everything in a given literal object except for the first key.
I found a solution that sort of works, but I feel like there is a better way to do it. Also, I can't figure out how to efficiently put space between the values in the variable.
The exercise says the final result should look something like this:
39 Johnson Ave, Brooklyn, NY, 11206
But mine looks like this:
39 Johnson AveBrooklynNY11206
Literal Object provided in exercise:
const restaurant = {
name: 'Ichiran Ramen',
address: `${Math.floor(Math.random() * 100) + 1} Johnson Ave`,
city: 'Brooklyn',
state: 'NY',
zipcode: '11206',
}
My solution:
let fullAddress = restaurant.address + restaurant.city + restaurant.state + restaurant.zipcode;

Given an array of strings, you can use values.join(', ') to put commas between the values cleanly. Then you could do e.g. [restaurant.address, restaurant.city, restaurant.state, restaurant.zipcode].join(', ').
If you wanted to do this more generically for any object, you could use Object.values(restaurant).slice(1).join(', ') to dynamically get all values after the first and comma delimit them.
In this case though, I think it makes the most sense to just explicitly append with commas since it's an address format (maybe you don't want a space after the zip code for example), so something like restaurant.address + ', ' + restaurant.city + ...

Regarding spaces (and commas), you can use a template string as done for restaurant.address.
const restaurant = {
name: 'Ichiran Ramen',
address: `${Math.floor(Math.random() * 100) + 1} Johnson Ave`,
city: 'Brooklyn',
state: 'NY',
zipcode: '11206',
};
let fullAddress = `${restaurant.address}, ${restaurant.city}, ${restaurant.state}, ${restaurant.zipcode}`;
console.log(fullAddress); // 39 Johnson Ave, Brooklyn, NY, 11206
Next, notice we're actually joining all the address-parts with the same delimiter: ', '. This means we can use [].join() instead.
const restaurant = {
name: 'Ichiran Ramen',
address: `${Math.floor(Math.random() * 100) + 1} Johnson Ave`,
city: 'Brooklyn',
state: 'NY',
zipcode: '11206',
};
let addressParts = [restaurant.address, restaurant.city, restaurant.state, restaurant.zipcode];
let fullAddress = addressParts.join(', ');
console.log(fullAddress); // 39 Johnson Ave, Brooklyn, NY, 11206
Lastly, (if you want to get fancy), note that restaurant. is repeated. This can be avoided with [].map().
const restaurant = {
name: 'Ichiran Ramen',
address: `${Math.floor(Math.random() * 100) + 1} Johnson Ave`,
city: 'Brooklyn',
state: 'NY',
zipcode: '11206',
};
let fullAddress = ['address', 'city', 'state', 'zipcode']
.map(key => restaurant[key])
.join(', ');
console.log(fullAddress); // 39 Johnson Ave, Brooklyn, NY, 11206

You can take out all the values from the restaurant object, remove the first element and then use join to get the desired string
const restaurant = {
name: 'Ichiran Ramen',
address: `${Math.floor(Math.random() * 100) + 1} Johnson Ave`,
city: 'Brooklyn',
state: 'NY',
zipcode: '11206',
}
const fullAddress = Object.values(restaurant).slice(1).join(', ');
console.log(fullAddress);

Related

How to merge nested json in snowflake?

object.assign is only perform the direct merge but its not working for nested json.
If anyone worked on this, could you please share the steps.
For example,I want to update the phone number and city of the user. City is under the location property. How should i update the value of city?
Example:
const user = {
name: "Liya",
phone: 12345,
location: {
city: "Camden",
country: "UK"
}
};
const updates = {
name: "David",
phone: 12345678,
location: {
city: "Smithfield"
}
};
Output should be like this:
console.log(Object.assign({}, user, updates));
{
name: 'Liya',
phone: 12345678,
location: {
country: 'UK',
city: 'Smithfield'
}
}
I'm assuming the name should be David since that's the name in the updates.
Based on #Han Moe Htet's comment, I used code from Vincent on that response. I used his because it does not require any external libraries, which Snowflake currently does not allow for Javascript UDFs.
There's an important consideration with this code. It uses recursion, and Snowflake UDFs have rather limited stack depth. If you have a highly nested object, it could run out of stack depth.
set USR = $${
name: "Liya",
phone: 12345,
location: {
city: "Camden",
country: "UK"
}
}$$;
set UPDATES = $${
name: "David",
phone: 12345678,
location: {
city: "Smithfield"
}
}$$;
create or replace function MERGE_OBJECTS("obj1" object, "obj2" object)
returns object
language javascript
strict immutable
as
$$
return merge(obj1, obj2);
function merge(current, updates) {
for (key of Object.keys(updates)) {
if (!current.hasOwnProperty(key) || typeof updates[key] !== 'object') current[key] = updates[key];
else merge(current[key], updates[key]);
}
return current;
}
$$;
with x as
(
select parse_json($USR) as USR, parse_json($UPDATES) as UPDATES
)
select merge_objects(USR, UPDATES) from X;

How to Filter an array of objects to find the objects that share cross referencing properties

So say for example I'm making a Social app, and I have a user whom I'm trying to make a group match for
const user = {Name: Stan, location: "Chicago", preferences: {locations: ["New York"]} }
and a collection of people objects like so
const matchPool =
[{Name: Bob, location: "New York", preferences: {locations: ["Chicago"]} },
{Name: Susan, location: "Miami", preferences: {locations: ["Chicago", "Miami"]} },
{Name: Tom, location: "Chicago", preferences: {locations: ["Chicago", "New York"]} },
{Name: Sally, location: "New York", preferences: {locations: ["Chicago", "LA"]} },
{Name: Carl, location: "New York", preferences: {locations: ["Detroit", "LA", "Chicago"]} }]
Say I wanted a group with Stan included, How would I go about filtering so that every member of the group has a location that is in the preferences of every other member of the group?
My first thought was to use lodash with a filter like so
const FilteredPeople = _.filter(matchPool, function(matchCandidate) {
return user.preferences.locations.indexOf(matchCandidate.location) != -1 &&
matchCandidate.preferences.locations.indexOf(user.location) != -1
});
If I add Stan to this group returned we would end up with the following
[{Name: Stan, location: "Chicago", preferences: {locations: ["New York"]}}
{Name: Bob, location: "New York", preferences: {locations: ["Chicago"]}},
{Name: Sally, location: "New York", preferences: {locations: ["Chicago", "LA"]}},
{Name: Carl, location: "New York", preferences: {locations: ["Detroit", "LA", "Chicago"]}}]
Notice the issue is that while Stan is an acceptable match for Bob, Sally, and Carl and vice versa, Bob/Sally/Carl are not acceptable matches for each other because none of them have New York as a location preference.
I realize its not possible from this small data set but given I have a large match pool with many people, how would I filter so that ALL people retuned are both compatible with the seed person(Stan) and each other?
Edit: there was some confusion so to say it another way
The location property is where that person is, the preference location array is the cities where that person is willing to meet other people from, so when we form a group all members need to have a location that is in the preference location array of every other member
See if this does it for you... it just keeps track of where each match is from to make sure we can check others against the current group. I changed Sally's preferences to include New York so she's included in the matches
const user = {Name: 'Stan', location: "Chicago", preferences: {locations: ["New York"]} }
const matchPool =
[{Name: 'Bob', location: "New York", preferences: {locations: ["Chicago"]} },
{Name: 'Susan', location: "Miami", preferences: {locations: ["Chicago", "Miami"]} },
{Name: 'Tom', location: "Chicago", preferences: {locations: ["Chicago", "New York"]} },
{Name: 'Sally', location: "New York", preferences: {locations: ["New York","Chicago"]} },
{Name: 'Carl', location: "New York", preferences: {locations: ["Detroit", "LA", "Chicago"]} }]
let matches=[]
let locs = [user.location]
matchPool.forEach(m=>{
//If a user from the pool matches, add them and also keep track of their location to ensure future matches
if (user.preferences.locations.indexOf(m.location)>-1 && locs.every(val => m.preferences.locations.includes(val))){
matches.push(m)
locs.push(m.location)
}
})
console.log(matches)
const matchPool = [
{Name: 'Bob', location: 'New York', preferences: {locations: ['Chicago']}},
{Name: 'Susan', location: 'Miami', preferences: {locations: ['Chicago', 'Miami']}},
{Name: 'Tom', location: 'Chicago', preferences: {locations: ['Chicago', 'New York']}},
{Name: 'Sally', location: 'New York', preferences: {locations: ['Chicago', 'LA']}},
{Name: 'Carl', location: 'New York', preferences: {locations: ['Detroit', 'LA', 'Chicago']}},
];
const target = {Name: 'Stan',location: 'Chicago',preferences: { locations: ['New York']}};
let matchGroup = matchPool.filter((user) => {
if (
// user in group prefers target's location
user.preferences.locations.includes(target.location) &&
// user's location inside targets prefered locations
target.preferences.locations.includes(user.location)
) {
return user;
}
});
matchGroup = [target, ...matchGroup];
console.log(JSON.stringify(matchGroup, null, 2));
The algorithm could look like this:
Start with a source - filter the db to all items that match. This is the "base-lvl0" (it ensures that our source cannot be ruled out later)
Take the 1. element from the "base-lvl0", and use it as the "source" for a second iteration to produce a "base-lvl1-1"
Take the 2. element from the "base-lvl0", and use it as the "source" for a second iteration to produce a "base-lvl1-2"
Take the 3. element from the "base-lvl0", and use it as the "source" for a second iteration to produce a "base-lvl1-3"
...
n. Take the nth element from the "base-lvl0" and use it as the "source" for a second iteration to produce a "base-lvl1-n"
By the nth step, you'll have a lot of smaller groups that are sure to satisfy at least 2 people. Now, do this with all the "base-lvl1-x" lists to create "base-lvl2-x" lists (to surely satisfy 3 people), then comes "base-lvl3-x", etc. up until all items from all lists have been used as "source".
This way you make sure that in all the FINAL lists everyone is in the preferential lists of everyone. I think this is a bit inefficient but deterministic & sure to satisfy the "location & preferred location" condition.
SUGGESTION:
Try to loosen up the conditions a bit or start to get deep into the beauties of graph theory.
This is quite cutting edge maths, and I think resembles your problem (in some ways): A Breakthrough in Graph Theory - Numberphile (2019)

Unable to properly convert array of complex objects to CSV

I have an array of complex objects, which may contain arrays of more objects. I want to convert these to a CSV file. Whenever there's a list of objects, the data is parsed as [object Object]. If a person has two emails, for example, I want to print these emails in two lines, and so on for each object. Addresses may be concatenated to one string, for example "France, Paris, someStreet 15".
The code is in this pen.
Here's the data:
var names = [
{
Name: [{First: "Peter", Last:"john"}],
WorkPlace: [{Company: "Intel", emails: ["jack#intell.com","admin#intell.com"]}],
Age: 33.45,
Adress: [{Country:"UK", city: "London", street:"Oak", strtNumber:16},
{Country:"Italy", city: "MIlan", street:"Zabin", strtNumber:2}]
},
{
Name: [{First: "jack", Last:"Smith"}],
WorkPlace: [{Company: "Intel", emails: ["jack#intell.com","admin#intell.com"]}],
Age: 30,
Adress: [{Country:"Portugal", city: "Lisbon", street:"crap", strtNumber:144},
{Country:"Greece", city: "Athenes", street:"Hercules", strtNumber:55}]
},
{
Name: [{First: "jon", Last:"snow"}],
WorkPlace: [{Company: "Intel", emails: ["jack#intell.com","admin#intell.com"]}],
Age: 50,
Adress: [{Country:"Middle earth", city: "Winterfell", street:"raven", strtNumber:4345},
{Country:"Narnia", city: "Jacksonvile", street:"Great crap", strNumber:34}]
},
];
Right now this is the output:
The mistake is inside your converArrayOfObjectsToCSV-method, as the result of 'item[key]' is an array (in case of 'Name') and you need to specify further how to handle this array, as it otherwise will only be written out to [object Object].
You will have to access the element with i.e. item[key][index] and the iterate over its properties and print them as you need them.
The [object Object] indicates the data needs further conversion to get the desired output.
Here is an updated CodePen with an example conversion.
The conversion routine provided uses Object.values() to convert all data:
function parseArrayOfObjects(arrayOfObj){
return arrayOfObj.map(item =>
Object.values(item).join(" ")) // convert each array item to it's values
.join(" ") // convert final array to string
.replace(",", " "); // remove any commas to preserve csv format
}
Of course, your needs may dictate other conversions, so adjust as needed.

Javascript - How to add multiple objects into an empty array

I am trying to add multiple objects- Company Names into listBox Companies. I used $scope.companies.push(newCompany[0].name); to add the company into the list. But only the first object's company gets added because I used newCompany[0].name.
Now, how do I add the second company name into the list without entering newCpmpany[1].name ? Say there are 50 companies, I cannot add all 50 by doing this. Is there a better way to add all the names in one go? like a loop or incrementing the element or something? Looking for some help. Thanks in advance.
var newCompany = [{
name: "Huawei", // -->COMPANY NAME
email: "Drath#yahoo.com",
phone: "123-123-1234",
owner: "Drath",
street: "Gin Blvd",
city: "Austin",
country: "USA",
duns:"123112321",
type: "buyer"
},
{
name: "Asus", // -->COMPANY NAME
email: "Vadar#yahoo.com",
phone: "999-123-8888",
owner: "Vadar",
street: "Vince Blvd",
city: "Dallas",
country: "USA",
duns: "123100000",
type: "supplier"
}];
window.localStorage.setItem("newCompany", JSON.stringify(newCompany));
$scope.companies = [];
var newCompany = JSON.parse(localStorage.getItem("newCompany"));
$scope.companies.push(newCompany[0].name);
You can try with spread
$scope.companies.push(...newCompany.map(item => item.name));
or why do you need exactly push? why don't you just init $scope.companies with exact values
var newCompany = JSON.parse(localStorage.getItem("newCompany"));
$scope.companies = newCompany.map(item => item.name)
If spread is not supported just a regular splice of array can be used
var names = newCompany.map(function(company){return company.name});
$scope.companies.splice(-1, 0, names);

Pulling array from object

Im trying to pull the gpa numbers from the array that is in the object and have them displayed in the console but my code keeps giving me undefined '0' error. Any help would be appreciated.
var fsInfo = {
name: 'John Doe',
address:{
street: '123 Some Street ',
city: 'Town, ',
state: 'HI',
gpa: [3.0,4.0,2.0]
}
}
console.log("GPA: " + fsInfo.gpa['0'],fsInfo.gpa['1'],fsInfo.gpa['2'])
Use
console.log("GPA: " + fsInfo.gpa[0],fsInfo.gpa[1],fsInfo.gpa[2])
Note: Array indices are numbers.
In your case, they are inside address. So you should do
console.log("GPA: " + fsInfo.address.gpa[0],fsInfo.address.gpa[1],fsInfo.address.gpa[2])
If your object had been like this
var fsInfo = {
name: 'John Doe',
address:{
street: '123 Some Street ',
city: 'Town, ',
state: 'HI'
},
gpa: [3.0,4.0,2.0]
}
then
console.log("GPA: " + fsInfo.gpa[0],fsInfo.gpa[1],fsInfo.gpa[2])
will work.

Categories

Resources