Javascript: How to combine two arrays with duplicate keys into an object - javascript

I have two arrays
array1 = [Alabama, Alabama, Georgia, Georgia, Georgia, California ]
array2 = [Mobile, Montgomery, Atlanta, Savannah, Montgomery, San Francisco ]
Both have equal number of elements and essentially for every city in Array 2, there is a corresponding state in the other array but as you can see city names in different states can be the same
I need to convert it into an Object like this in Javascript - This way I can populate a conditional drop down easily when a state is chosen unless someone has an idea to do the same with 2 distinct arrays
var citiesByState = {
Alabama: ["Mobile","Montgomery"],
Georgia: ["Savannah","Montgomery"],
California: ["San Francisco"]
}
Any help would be greatly appreciated
I have tried a few different ways but they create objects of objects as opposed to what I want above.

The Solution :
Don't forget to give a feedback.
const array1 = ['Alabama', 'Alabama', 'Georgia', 'Georgia', 'Georgia', 'California' ];
const array2 = ['Mobile', 'Montgomery', 'Atlanta', 'Savannah', 'Montgomery', 'San Francisco'];
const objProps = Array.from(new Set(array1));
const citiesByState = {};
objProps.forEach(state => {
citiesByState[state] = [];
})
array1.forEach((state, idx) => {
citiesByState[state].push(array2[idx]);
})
console.log(citiesByState);

I believe the following code solves your question.
let array1 = ["Alabama", "Alabama", "Georgia", "Georgia", "Georgia", "California"];
let array2 = ["Mobile", "Montgomery", "Atlanta", "Savannah", "Montgomery", "San Francisco"];
let citiesByState = {};
for (let [index, state] of array1.entries()) {
if (!citiesByState[state]) {
// if the state has not been added yet, add it
citiesByState[state] = [];
}
// push the corresponding city index onto the state array
citiesByState[state].push(array2[index]);
}
console.log(citiesByState);

Here is an example with reduce:
let array1 = ['Alabama', 'Alabama', 'Georgia', 'Georgia', 'Georgia', 'California' ]
let array2 = ['Mobile', 'Montgomery', 'Atlanta', 'Savannah', 'Montgomery', 'San Francisco' ]
let result = array1.reduce((memo, state, idx) => {
if(!memo[state]){
memo[state] = array2[idx];
} else {
const rest = Array.isArray(memo[state]) ? memo[state].flat() : [memo[state]]
memo[state] = [array2[idx], ...rest];
}
return memo;
}, {});
console.log(result)

Clean and fewer lines
var array1 = ["Alabama", "Alabama", "Georgia", "Georgia", "Georgia", "California", "Alabama"];
var array2 = ["Mobile", "Montgomery", "Atlanta", "Savannah", "Montgomery", "San Francisco", "test"];
const res = array1.reduce((ac,a, index) => {
let key = a;
ac[key] = ac[key] || [];
ac[key].push(array2[index])
return ac;
}, {});
console.log(res)

Related

How do I search a string "backwards"?

I have the following code in Angular. I want to be able to find "north america" by typing "america north". How do I do that?
const getContinents = keys =>
[
'africa',
'antarctica',
'asia',
'australia',
'europe',
'north america',
'south america'
].filter(e => e.indexOf(keys.toLowerCase()) > -1);
const fakeContinentsRequest = keys =>
of(getContinents(keys)).pipe(
tap(_ => console.log(`API CALL at ${new Date()}`))
);
fromEvent(document.getElementById('type-ahead'), 'keyup')
.pipe(
debounceTime(200),
map((e: any) => e.target.value),
distinctUntilChanged(),
switchMap(fakeContinentsRequest),
tap(c => (document.getElementById('output').innerText = c.join('\n')))
)
.subscribe();
You could split() both string on spaces to get an array of each word.
Then we can use every() to check if input exist in search. This way the 'order' is not important.
Combining this with find() to search for the matching result in an array:
const options = [ 'africa', 'antarctica', 'asia', 'australia', 'europe', 'north america', 'south america' ];
function findByWord(input) {
let inputSplit = input.split(' ');
return options.filter(o => o.split(' ').every(e => inputSplit.includes(e)));
}
const res = findByWord('america north');
console.log(res)
[
"north america"
]
Simplest solution is just to reverse those words you've been given, and assume all casing is correct:
const matchStr = "I Love PHP";
const searchStr = "PHP Love";
if (matchStr.includes(searchStr.split(" ").reverse().join(" "))) {
console.log("Value matched: " + matchStr);
}
To implement into your current code, a little more annoying but you can just add an OR condition to your filter line:
.filter(e => (e.indexOf(keys.toLowerCase()) > -1) || (e.indexOf(keys.toLowerCase().split(" ").reverse().join(" ")) > -1));
I made something more dynamic, where I split the search string and then loop through them inside an Array.filter(). It's possible that it's easier to achieve this using a regexp. I also added a requirement that the search should ignore words that are shorter than two characters, and also mapped the keywords to be lowercase so they are case insensitive.
const continents = [
'africa',
'antarctica',
'asia',
'australia',
'europe',
'north america',
'south america'
]
const filterContinents = (searchStr, continents) => {
const MIN_KEYWORD_LENGTH = 2;
let keywordsArr = searchStr.split(' ')
.filter((keyword) => keyword.length > MIN_KEYWORD_LENGTH)
.map((keyword) => keyword.toLowerCase());
let hasKeywords = keywordsArr.length > 0;
const filterByKeywords = (_contintent) => {
for (const _keyword of keywordsArr) {
if (!_contintent.includes(_keyword)) {
return false
}
}
return hasKeywords
}
return continents.filter(filterByKeywords);
}
let searchStr = 'eur';
console.log({searchStr}, filterContinents(searchStr, continents));
searchStr = 'eu ro pe';
console.log({searchStr}, filterContinents(searchStr, continents));
searchStr = 'America North';
console.log({searchStr}, filterContinents(searchStr, continents));

continously add to an objects key value in javascript

I am running a loop over some data. I have an object with a key value message. Every time I loop over my array I want to append to this objects key value, I tried using spread operator but not having any luck
const arr1 = [
"keith",
"kelly",
"ed",
"shelby"
]
const arr2 = [
"Parker",
"Morgan",
"Arnold",
"Suski",
"Parks"
]
const addToObjectsMessageKey = arr1.map((name) => {
let obj = {}
arr2.forEach((lastName) => { return {...obj, message: ...obj.message + name}})
return obj
})
console.log(addToObjectsMessageKey)
expected output
addObjectsToMessageKey = [
{ message: "Parker Morgan Arnold Suski Parks" },
{ message: "Parker Morgan Arnold Suski Parks" },
{ message: "Parker Morgan Arnold Suski Parks" },
{ message: "Parker Morgan Arnold Suski Parks" },
]
Looks like you want to overwrite the arr1 elements to an object with all the elements on the arr2 joined by space, you can simplify this using arr.join MDN documentation instead of forEach
const arr1 = ["keith", "kelly", "ed", "shelby"];
const arr2 = ["Parker", "Morgan", "Arnold", "Suski", "Parks"];
const addToObjectsMessageKey = arr1.map(() => {
return {
message: arr2.join(" ")
};
});
console.log(addToObjectsMessageKey);
Here is a codeSandbox:
https://codesandbox.io/s/agitated-mestorf-tlhkh2?file=/src/index.js:0-248
Is this what you want?

How to convert particular key value from object to array javascript

I would like to know how to get particular key from object and convert to array
in javascript
var result = Object.entries(obj).includes(obj.name || obj.country || obj.account || obj.pincode).map(e=>e);
var obj = {
"name" : "Sen",
"country": "SG",
"key" : "Finance",
"city": "my",
"account":"saving",
"pincode":"1233"
}
Expected Output
["Sen", "SG", "saving", "1233"]
Create an array of requested keys, and then map it and take the values from the original object:
const obj = {"name":"Sen","country":"SG","key":"Finance","city":"my","account":"saving","pincode":"1233"}
const keys = ['name', 'country', 'account', 'pincode']
const result = keys.map(k => obj[k])
console.log(result) // ["Sen", "SG", "saving", "1233"]
I think you can try it like this.
There're other ways to get that result, too. Here's just a simple solution.
var obj = {
"name" : "Sen",
"country": "SG",
"key" : "Finance",
"city": "my",
"account":"saving",
"pincode":"1233"
}
let arrObj = []
let result = arrObj.push(obj.name, obj.country, obj.account, obj.pincode)
console.log(arrObj)
filter by a Set containing just the keys you want, then use map to return just the values:
const keys = new Set(['name', 'country', 'account', 'pincode'])
Object.entries(obj).filter(entry => keys.has(entry[0])).map(entry => entry[1])
If you want an array based on a known, hardcoded list of properties, the easiest option is an array literal:
const result = [obj.name, obj.country, obj.account, obj.pincode];
A benefit of this approach is that it guarantees the order of values in the array. While the order is predictable in your example (one onject literal), f your objs are created in different places, the order of the values may not always be the same.
var obj = {
"name" : "Sen",
"country": "SG",
"key" : "Finance",
"city": "my",
"account":"saving",
"pincode":"1233"
}
const Names = Object.keys(obj);
console.log(Names);
const Values = Object.values(obj);
console.log(Values);
const entries = Object.entries(obj);
console.log(entries);

Map one property from object array to another object in different object array

I have two object array. let's say Shop array & Country array. An Shop array's one object has {id:01,name:'name of the shop',countryCode:'USA'} and Country array's one object has {code:'USA', country:'United States of America'} i want to map shop's object the country code to country's object country an create new object array.in new object array, one object should look like this.
{id:01,name:'name of the shop',countryCode:'USA',country:'United States of America'}
what is the most optimized way to do this
let shopArray=[{id:01,name:'name of the shop',countryCode:'USA'}]
let countryArray=[{code:'USA', country:'United States of America'}]
let mapedShopArray=shopArray.map(eachShop=>{
for(let eachCountry of countryArray){
if(eachCountry.code==eachShop.countryCode){
eachShop.country =eachCountry.country;
break;
}
}
return eachShop;
})
console.log(mapedShopArray)
You can do this
let shopArrayObj = [{ id: 01, name: "shop1", countryCode: 'USA' },
{ id: 02, name: "shop2", countryCode: 'US' },
{ id: 03, name: "shop3", countryCode: 'ENG' }]
let countryArrayObj = [{ code: 'USA', country: 'United States of America' },
{ code: 'ENG', country: 'England' }]
let finalArrayOb = []
shopArrayObj.map(shop => {
countryArrayObj.map(country => {
if (country.code === shop.countryCode) {
let obj = { ...shop, ...country, }
delete obj.code
finalArrayOb.push(obj)
}
})
})
console.log(finalArrayOb)
You could do something like this.
let shopArr = [{id:01,name:'name of the shop',countryCode:'USA'}];
let countryArr = [{code:'USA', country:'United States of America'}];
let newArr = shopArr.map((shop) => {
return {...shop, country: countryArr.find(country => {country.code === shop.countryCode}).country};
});
You can do like this:
let country1 = [{code:'USA', country:'United States of America'}]
let shop1 = [{id:01,name:'name of the shop',countryCode:'USA'}]
country1.forEach((item1) => {
shop1.forEach((item2) => {
if(item1.code === item2.countryCode) {
arr.push({'id': item2.id, 'name': item2.name, 'countryCode': item2.countryCode, 'country': item1.country})
}
})
})
Hope this helps.
If you can restructure Country as an object, instead of an array, we will be able to achieve the result using single for loop. Working code is given below.
var country = {
"USA": "United States of America",
"IN": "India",
"UAE": "United Arab Emirates",
"UK": "United Kingdom"
}
var shopArray = [{id:01,name:'name of the shop',countryCode:'USA'}, {id:02,name:'name of another shop',countryCode:'UK'}]
for(var i=0;i<shopArray.length; i++){
var countryCode = shopArray[i].countryCode;
shopArray[i].country = country[countryCode];
}
console.log(shopArray)
This code will actually modify original shopArray, instead of giving a new array.
You can do it as follows.
const array1 = [{ id: 1, name:'My Shop', countryCode:'USA' }, { id: 2, name:'My Shop2', countryCode:'UK' }];
const array2 = [{ code:'USA', country:'United States of America' }, { code:'UK', country:'United Kingdom' }];
let myArray = [];
array1.forEach(item1 => {
array2.forEach(item2 => {
if (item1.countryCode === item2.code) {
let obj = {...item1, country: item2.country };
myArray.push(obj)
}
});
});
Demo

Adding an array as a new key-value pair

I have an existing array which contains key-value pairs for a series of items:
resultsArray = [
{
parkName: "Central Park",
owner: "NYC"
},
{
parkName: "Patterson Park",
owner: "Baltimore"
}
]
I'd like to add an additional key-value pair to each item where the value is an array of amenities. For example: if Central Park includes a dog park, jogging trail, and basketball courts, and Patterson Park includes a baseball field and a rec center, when the amenities were added to the array, the resultsArray would now look like:
resultsArray = [
{
parkName: "Central Park",
owner: "NYC",
amenities: "Dog Park", "Jogging Trail", "Basketball Courts"
},
{
parkName: "Patterson Park",
owner: "Baltimore",
amenities: "Baseball Fields", "Recreation Center"
}
]
I'm relatively new to Javascript, but I've successfully created an array of amenities for each of the parks. I then tried to add each amenityArray as follows:
resultsArray.push({
amenities: amenityArray
});
However, this didn't give me what I wanted.
Can someone demonstrate how I would add the amenityArray as a key-value pair for each of the parks?
For each object in resultsArray, add the corresponding amenity.
for (let i = 0; i < resultsArray.length; i++) {
resultsArray[i][i]['amenities'] = amenityArray[i];
}
A more verbose version would be
for (let i = 0; i < resultsArray.length; i++) {
let result = resultsArray[i]; // i is an index
let innerResult = result[i]; // i is a key
innerResult['amenities'] = amenityArray[i];
}
Iterate the array and add a new key-value pair in the inner objects.
Note: Picked the amenities dynamically.
resultsArray = [{ 0: { parkName: "Central Park", owner: "NYC" } }, { 1: { parkName: "Patterson Park", owner: "Baltimore" } }];
amenities = { "0": "X Park, Y Park, Z Park", "1": "A Park, B park, C Park" };
[...resultsArray].forEach(token => {
Object.keys(token).forEach(key => token[key]['amenities'] = amenities[key]);
})
console.log(resultsArray);
You can use map for this:
const newArray = resultsArray.map((item, i) => {
item[i].amenities = amenityArray[i];
return item;
});
Also your array structure looks weird, you should consider removing those redundant nested objects, and then it will be easier to iterate:
resultsArray = [{
parkName: "Central Park",
owner: "NYC"
},
{
parkName: "Patterson Park",
owner: "Baltimore"
}
]
const newArray = resultsArray.map((item, i) => {
item.amenities = amenityArray[i];
return item;
});
You can use .forEach() to loop through the array and set each item depend on index:
var resultsArray = [{parkName: "Central Park",owner: "NYC"},{parkName: "Patterson Park", owner: "Baltimore"}]
var amenityArray = [["Dog Park", "Jogging Trail", "Basketball Courts"], ["Baseball Fields", "Recreation Center"]];
resultsArray.forEach((val, index) => {val.amenities = amenityArray[index]})
console.log(resultsArray)

Categories

Resources