I’ve two arrays of objects with name value and id
Array A
ArrayA: [{
name: ,
value: ,
key:
},
];
I’ve another array of objects but with diffretns names of properties
ArrayB: [{
user: “userA” ,
email: “emailA”,
key:1:
},
{
user: “userB” ,
email: “emailB”,
key:
},
];
Now I want to ThatArrayA will have the values from ArrayB. I mean user => name and email => value
ArrayA should have the following entries
ArrayA: [{
name: “userA” ,
value: “emailA”,
key: 1
},
name: “userB” ,
value: “emailB”,
key: 1
]
I’ve tried to use map but without success, any idea what am I missing here?
ArrayA = ArrayB.map(((item: { name: string; value: string }) => (item.user, item.email))
I Can use a loop, there is better way to to it ?
Should I use lodash?
I think ArrayA is useless here,
You can just use map() over ArrayB and return the Array with the properties you need.
const ArrayB = [
{
user: "dani" ,
email: "dani#gmail.com",
key:1
},
{
user: "john" ,
email: "john#gmail.com",
key:2
}
]
const res = ArrayB.map(({ user, email, key }) => ({
name: user,
value: email,
key
}));
console.log(res);
It's better to use spread operator and map:
const result = [...ArrayA, ...ArrayB.map(({ key, user, email }) => ({ key, name: user, value: email }))]
You have to use the Array concat() Method.
let ArrayA = [
{
name: 'name1',
value: '22',
key: 5,
},
];
let ArrayB = [
{
name: 'name2',
value: '33',
key: 6,
},
];
let ArrayC = ArrayA.concat(ArrayB);
let ArrayD = ArrayA.concat([{ name: 'name2' }, { value: '33' }, { key: 6 }]);
console.log(ArrayC);
console.log(ArrayA);
console.log(ArrayD); //ref sreenshot
You can't have elements in the array directly like what you have specified, they need to an object to have a key value relationship
You can rename the key by maintaining an object. Something like this:
var obj={ user:'name', email:'value', key:'key' };
var arrayA=[{name:'somevalue', value:'somevalue', key:''}];
var arrayB= [{ user: 'userA' , email: 'emailA', key:'1' }, { user: 'userB' , email: 'emailB', key:'' }];
arrayA = [...arrayA, ...arrayB.map(k=>Object.fromEntries(Object.entries(k).map(([key,v])=>[obj[key],v])))];
console.log(arrayA)
Depending on the size of these objects having a means of translation might be nice.
Plain old JavaScript with Object.fromEntries has a solution. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries
objA = {
name: 'user',
value: 'email',
key: 1
};
objB = {
user: 'user',
email: 'email',
key: 1
};
function translate(object) {
return Object.fromEntries(
Object.entries(objB)
.map(([key, value]) => {
let newKey;
switch(key) {
case 'user':
newKey = 'name';
break;
case 'value':
newKey = 'email';
break;
default:
newKey = key;
}
return [newKey, value];
})
);
}
const originalObject = Object.fromEntries(Object.entries(objB));
const newObject = translate(originalObject);
console.log(originalObject);
console.log(newObject);
With an output of:
{ user: 'user', email: 'email', key: 1 }
{ name: 'user', email: 'email', key: 1 }
You can map the arrays with the function just as you have in your solution.
Related
I have a request data - array of object like below:
const requestData = [
{
name: 'Test1',
address: 'FL',
},
{
name: 'Test2',
address: 'AL',
},
{
name: 'Test3',
address: 'AK',
},
];
I want to manipulate the object properties based on the index (that mean if index 0 change name property to USER_NAME, if index 1 means change to EMP_NAME) and convert it into final object as below:
const finalResult = {
USER_NAME: 'Test1',
USER_ADDRESS: 'FL',
EMP_NAME: 'Test2',
EMP_ADDRESS: 'AL',
CUST_NAME: 'Test3',
CUST_ADDRESS: 'AK',
};
Using reduce() and an extra map array can do it
let data = [{
name: 'Test1',
address: 'FL',
},
{
name: 'Test2',
address: 'AL',
},
{
name: 'Test3',
address: 'AK',
},
]
let mdata =['USER_','EMP_','CUST_']
let result = data.reduce((a,v,i) =>{
let key = mdata[i]
a[key+'NAME'] = v.name
a[key+'ADDRESS'] = v.address
return a
},{})
console.log(result)
You could destructure and construct your final result:
const [ user, emp, cust ] = requestData;
const finalResult = {
USER_NAME: user.name,
USER_ADDRESS: user.address,
EMP_NAME: emp.name,
EMP_ADDRESS: emp.address,
CUST_NAME: cust.name,
CUST_ADDRESS: cust.address
};
Alternatively, you could reduce, but the code winds up being a bit more complicated than is necessary for this particular example:
const keys = [ "USER", "EMP", "CUST" ];
const finalResult = requestData.reduce(( out, { name, address }, index ) => {
out[ `${ keys[ index ] }_NAME` ] = name;
out[ `${ keys[ index ] }_ADDRESS` ] = address;
return out;
}, {});
I have an array of objects in the format below and would like to transform it into a new array of objects using a property as a key. The key should be unique. See shape of the object below
const mockedList = [
{
email: 'aaa#example.com',
id: '5052',
name: 'Java',
},
{
email: 'bbb#example.com',
id: '5053',
name: 'Python',
},
{
email: 'aaa#example.com',
id: '5054',
name: 'C#',
},
{
email: 'bbb#example.com',
id: '5055',
name: 'Javascript',
},
];
I would like to transform this and get an array of objects with keys and values in this format.
[
{
email: 'bbb#example.com',
languages: [
{
email: 'bbb#example.com',
id: '5055',
name: 'Javascript',
},
{
email: 'bbb#example.com',
id: '5053',
name: 'Python',
},
]
},
{
email: 'aaa#example.com',
languages: [
{
email: 'aaa#example.com',
id: '5052',
name: 'Java',
},
{
email: 'aaa#example.com',
id: '5054',
name: 'C#',
},
]
}
]
I've tried using map-reduce
const result = mockedList.reduce((r, a) => {
r[a.email] = r[a.email] || [];
r[a.email].push(a);
return r;
}, Object.create(null));
But did not get the right shape of data
You can do:
const mockedList = [{email: 'aaa#example.com',id: '5052',name: 'Java',},{email: 'bbb#example.com',id: '5053',name: 'Python',},{email: 'aaa#example.com',id: '5054',name: 'C#',},{ email: 'bbb#example.com', id: '5055', name: 'Javascript' },]
const mockedListHash = mockedList.reduce((a, c) => {
a[c.email] = a[c.email] || { email: c.email, languages: [] }
a[c.email].languages.push(c)
return a
}, {})
const result = Object.values(mockedListHash)
console.log(result)
In case you want to clean the repeated emails within languages:
const mockedList = [{email: 'aaa#example.com',id: '5052',name: 'Java',},{email: 'bbb#example.com',id: '5053',name: 'Python',},{email: 'aaa#example.com',id: '5054',name: 'C#',},{ email: 'bbb#example.com', id: '5055', name: 'Javascript' },]
const mockedListHash = mockedList.reduce((a, c) => {
a[c.email] = a[c.email] || { email: c.email, languages: [] }
a[c.email].languages.push({
id: c.id,
name: c.name,
})
return a
}, {})
const result = Object.values(mockedListHash)
console.log(result)
Here is another option with simple for loop
// Array
const mockedList = [
{
email: 'aaa#example.com',
id: '5052',
name: 'Java'
},
{
email: 'bbb#example.com',
id: '5053',
name: 'Python'
},
{
email: 'aaa#example.com',
id: '5054',
name: 'C#'
},
{
email: 'bbb#example.com',
id: '5055',
name: 'Javascript'
}
];
// Set new object
const newObj = {};
// Use regular loop
for(const el of mockedList) {
// Use email as key
// If key already exist, add info
// to it's languages array
if(newObj[el.email]) newObj[el.email].languages.push(el);
else newObj[el.email] = {
email: el.email,
languages: [el]
}
}
// Test
console.log(newObj);
// If you need just array of objects,
// without email as key, then transform it
const newArr = Object.keys(newObj).map((key) => newObj[key]);
// Test
console.log(newArr);
I have an array of objects sample for example :
const data = [
{
Name: 'test_1',
Value: '175',
Description: 'desc_1'
},
{
Name: 'test_2',
Value: '175',
Description: 'desc_2'
}
]
And an env file where I mark the data I want :
Name=true
Value=true
Description=false
How do I filter out the data file to only return the values of the keys Name and Value?
Desired output :
[
{
Name: 'test_1',
Value: '175'
},
{
Name: 'test_2',
Value: '175',
}
]
There are different ways in order to achieve the required output, here I'm making use of Array.map and Array.reduce methods.
const data = [{ Name: 'test_1', Value: '175', Description: 'desc_1', }, {Name: 'test_2', Value: '176', Description: 'desc_2', }];
//In order to access from the env file
/*
const fields = {
Name: process.env.Name,
Value: process.env.Value,
Description: process.env.Description
}
*/
//For the snippet purpose i'm using this hardcoded values
const fields = {
Name: true,
Value: true,
Description: false
}
//Convert the object to an array of keys whose values are needed from the original data
const getConfigData = fields => Object.keys(fields).filter(key => fields[key])
let config = getConfigData(fields);
const getSelectedKeyValues = (data, config) => {
return data.map(obj => config.reduce((acc, c) => (acc[c] = obj[c], acc), {}));
}
console.log("Name & Value:", getSelectedKeyValues(data, config));
.as-console-wrapper {
max-height: 100% !important;
}
You can do it like this:
const data = [
{ Name: 'test_1', Value: '175', Description: 'desc_1' },
{ Name: 'test_2', Value: '175', Description: 'desc_2' }
]
let results = data.map((item) => {
new_item = {};
if (process.env.Name) new_item.Name = item.Name;
if (process.env.Value) new_item.Value= item.Value;
if (process.env.Description) new_item.Description= item.Description;
return new_item;
})
Since your example is a JS array and no JSON string, you can use map:
const result = data.map(d => { return {Name: d.name, Value: d.Value }});
Another solution would be filtering the objects entries when mapping and creating a new object from those entries.
const data = [{
Name: 'test_1',
Value: '175',
Description: 'desc_1'
},
{
Name: 'test_2',
Value: '175',
Description: 'desc_2'
}
]
const status = {
Name: true,
Value: true,
Description: false
}
// props you want to keep
const keep = Object.keys(status).filter((k) => status[k]);
const result = data.map((d) => {
// create object from entries based on what you want to keep
return Object.fromEntries(Object.entries(d).filter(([k]) => {
return keep.includes(k)
}));
})
console.log(result);
I have an array of objects. I want to pick few values from my array of objects and send it in my request params on for my api that i am calling on componentDidMount.
My Array-
const myArray = [
{
id:'73',
name:'ABC',
age: '20',
},
{
id:'74',
name:'XYZ',
age: '21',
},
{
id:'75',
name:'PQR',
age: '22',
},
{
id:'76',
name:'TUV',
age: '23',
}
]
useEffect(
() => {
const newData = myArray.map(list => {
// Logic to add few more keys to existing array
return newData; // new array with few additional properties
});
let data= newData.map(({name, age}) => ({name,age}));
const reqParams = {
userData: {
data: [
{
data,
},
],
},
};
getUserData(reqParams); // API call
[],
);
To get values, I am doing like this-
let result = myArray.map(({name, age}) => name,age)
This will return me an array so, I am not sure if this is the right way to do it. trying to understand how can i pass the values to my request params.
Here is the sample code to achieve the desired output in a single loop 🚀
const myArray = [{
id: '73',
name: 'ABC',
age: '20',
}, {
id: '74',
name: 'XYZ',
age: '21',
}, {
id: '75',
name: 'PQR',
age: '22',
}, {
id: '76',
name: 'TUV',
age: '23',
}]
const newArr = myArray.map((d,index) => {
// return new obj structure with subset of myArray and extra values
const extraData = {
company: 'foo', // adding company & city [read/get it from anywhere]
city:'bar',
sampleIndex: index+1
}
const newObj = {
name: d.name, // not adding id, age
...extraData
}
return newObj
})
console.log("newArr ", newArr)
const reqParams = {
userData: {
data: newArr
},
};
console.log("reqParams ", reqParams)
You can create new object in map callback by wrapping it in ({}) braces
let data= myArray.map(({name, age}) => ({name,age}));
const reqParams = {
userData: {
data
},
};
Please try to write the newData calculation as follows if not already:
const newData = myArray.map(list => {
return {
...list,
key: value // additional property
}
});
I have two arrays. I merge it and remove duplicates. Merging is done by taking into consideration all keys of the arrays (all key values in the object in array 1 must match with those in array 2).
var result1 = [{
name: 'Sandra',
email: 'sandra#example.com'
},
{
name: 'John',
email: 'johnny#example.com'
},
{
name: 'Peter',
email: 'peter#example.com'
},
{
name: 'Bobby',
email: 'bobby#example.com'
},
{
name: 'Arun',
email: 'arun#gmail.com'
},
];
var result2 = [{
name: 'John',
email: 'johnny#example.com'
},
{
name: 'Bobby',
email: 'bobby#example.com'
},
{
name: 'Arun',
email: 'arun#example.com'
}
];
var result= _.uniqWith(_.concat(result1, result2), _.isEqual)
Now I need to check each item of merged array with each item of array1 and array2 and update the merged array if they are present or not.
So my end result should be like this.
var result = [{
name: 'Sandra',
email: 'sandra#example.com',
presentInA: true,
presentInB: false
},
{
name: 'John',
email: 'johnny#example.com',
presentInA: true,
presentInB: true
},
{
name: 'Peter',
email: 'peter#example.com',
presentInA: true,
presentInB: false
},
{
name: 'Bobby',
email: 'bobby#example.com',
presentInA: true,
presentInB: true
},
{
name: 'Arun',
email: 'arun#example.com',
presentInA: false,
presentInB: true
},
{
name: 'Arun',
email: 'arun#gmail.com',
presentInA: true,
presentInB: false
}
];
How do I go about doing this in the best way? I think I can do it with iterating through all 3 arrays, but its a bad way of doing that.
Please advice.
You can do something like this
result.map(
per => ({
name: per.name,
email: per.email,
presentInA: _.find(
result1, (o) => o.nombre === per.nombre && o.email === per.email
) ? true : false,
presentInB: _.find(
result2, (o) => o.nombre === per.nombre && o.email === per.email
) ? true : false,
})
)
You could iterate over result and use _.some in order to check whether each object inside it is in result1 and result2 (and set the corresponding properties presentInA and presentInB). Something like this:
_.forEach(result, (obj) => {
let presentInA = _.some(result1, obj);
let presentInB = _.some(result2, obj);
obj.presentInA = presentInA;
obj.presentInB = presentInB;
});
var result1 = [{
name: 'Sandra',
email: 'sandra#example.com'
},
{
name: 'John',
email: 'johnny#example.com'
},
{
name: 'Peter',
email: 'peter#example.com'
},
{
name: 'Bobby',
email: 'bobby#example.com'
},
];
var result2 = [{
name: 'John',
email: 'johnny#example.com'
},
{
name: 'Bobby',
email: 'bobby#example.com'
},
{
name: 'Arun',
email: 'arun#example.com'
}
];
var result = _.uniqWith(_.concat(result1, result2), _.isEqual);
_.forEach(result, (obj) => {
let presentInA = _.some(result1, obj);
let presentInB = _.some(result2, obj);
obj.presentInA = presentInA;
obj.presentInB = presentInB;
});
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>
You could use a hashtable for finding & merging dupes:
// Merges objects with the same name and email, sets the [arrName] property of the merged object to true
// also takes an optional settings object for chaining
function merge(arr, arrName, { hash = {}, result = [] } = {}) {
for(const { name, email } of arr) {
// Build up a hopefully unique key
const key = name + "#" + email;
// If its not in the hash yet, add it to the hash and the result
if(!hash[key])
result.push(hash[key] = { name, email });
// then set the key
hash[key][arrName] = true;
}
// allow chaining by exposing both hash and result
return { hash, result, merge: (arr, arrName) => merge(arr, arrName, { hash, result }) };
}
That could be used as:
const { result } = merge(result1, "presentInA").merge(result2, "presentInB");
That is O(n) but assumes that emails do not contain two #s.