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
}
});
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 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 need to implement a search function for a table.
I got an array of objects with unnecessary object properties.
I need to map the array to get necessary properties and then do the filtration.
This is my code.
const items = [
{
name: 'pathum',
id: 1,
status: true,
createdAt: 'KKKK',
country: {
name: 'SL',
code: 12,
},
},
{
name: 'kasun',
id: 1,
status: true,
createdAt: 'KKKK',
country: {
name: 'USA',
code: 23,
},
},
{
name: 'hansi',
id: 1,
status: true,
createdAt: 'KKKK',
country: {
name: 'GERMANY',
code: 34,
},
},
];
const tableColumns = ['name', 'country.name'];
const onSearch = (e) => {
e = e.toLowerCase();
const mappedItems = items.map((item) => {
Object.keys(item).forEach((key) => {
if (!tableColumns.includes(key)) delete item[key];
});
return item;
});
if (e) {
const result = mappedItems.filter((item) => {
const str = JSON.stringify(item).toLowerCase();
if (str.search(e) >= 0) return item;
});
return result;
} else {
return mappedItems;
}
};
console.log(onSearch('GERMANY'));
In an item object, I only need to get these two fields
const tableColumns = ['name', 'country.name'];
But this only gives me the name property
const mappedItems = items.map((item) => {
Object.keys(item).forEach((key) => {
if (!tableColumns.includes(key)) delete item[key];
});
return item;
});
My first question is how to map to expect a result like this
{
name: 'pathum',
country: {
name: 'SL',
},
},
Second question is JSON.stringtfy map whole object. So If I search "name" it will return all the objects becasue "name" is there in the all records in the stringtify string.
How do I avoid keys in the object when doing the stringify?
Hope my question is clear to you all.
How do I modify this code to get that expected functionality?
const tableColumns = ['name', 'country'];
const deleteProp = ['code'];
const mappedItems = items.map((item) => {
Object.keys(item).forEach((key) => {
console.log(key);
if (!tableColumns.includes(key)) delete item[key];
if(key == 'country') delete item[key][deleteProp[0]];
});
return item;
});
This may answer your first question.
You can check if the object has any of the tableColumns paths which includes the searched text. And then get a subset of the filtered objects and only include the tableColumns properties
const items=[{name:"pathum",id:1,status:true,createdAt:"KKKK",country:{name:"SL",code:12,},},{name:"kasun",id:1,status:true,createdAt:"KKKK",country:{name:"USA",code:23,},},{name:"hansi",id:1,status:true,createdAt:"KKKK",country:{name:"GERMANY",code:34}}],
tableColumns = ['name', 'country.name'];
function onSearch(array, e) {
const output = [];
for (const o of array) {
const hasProp = tableColumns.some(path => getProperty(o, path).includes(e))
if (hasProp)
output.push(subSet(o, tableColumns))
}
return output
}
function getProperty(o, path) {
return path.split('.').reduce((acc, p) => acc?.[p], o) || ''
}
function subSet(o, paths) {
const output = {}
for (const path of paths) {
let keys = path.split('.'),
last = keys.pop(),
value = o;
const final = keys.reduce((acc, k) => {
value = value?.[k]
return acc[k] ||= {}
}, output);
final[last] = value?.[last];
}
return output;
}
console.log(onSearch(items, 'pat'));
console.log(onSearch(items, 'kasun'));
First, don't change data. You can clone the data and change it.
And, search should be search. Don't put the data formation in it.
Let's start.
const items = [
{
name: 'pathum',
id: 1,
status: true,
createdAt: 'KKKK',
country: {
name: 'SL',
code: 12,
},
},
{
name: 'kasun',
id: 1,
status: true,
createdAt: 'KKKK',
country: {
name: 'USA',
code: 23,
},
},
{
name: 'hansi',
id: 1,
status: true,
createdAt: 'KKKK',
country: {
name: 'GERMANY',
code: 34,
},
},
];
// We will use object to get the fields you want. To reuse, you can add more fields you want.
const tableColumns = {
// id: 1,
name: 1,
country: {
name: 1
}
}
// getting the mapped items
const mappedItems = items.map((item) => {
const temp = {};
Object.keys(item).forEach((key) => {
const target = tableColumns[key];
if (target) {
if (typeof target === 'number'){
temp[key] = item[key];
} else {
temp[key] = {};
Object.keys(target).forEach(subKey => temp[key][subKey] = item[key][subKey]);
}
}
});
return temp;
});
// search function, use local varibles
const onSearch = (array, countryName) => {
return array.find(element => element.country.name.toLowerCase() === countryName.toLowerCase())
}
const searchResult = onSearch(mappedItems, 'germany');
console.log(searchResult);
You can just create a new array using Array.map
const items = [{
name: 'pathum',
id: 1,
status: true,
createdAt: 'KKKK',
country: {
name: 'SL',
code: 12,
},
},
{
name: 'kasun',
id: 1,
status: true,
createdAt: 'KKKK',
country: {
name: 'USA',
code: 23,
},
},
{
name: 'hansi',
id: 1,
status: true,
createdAt: 'KKKK',
country: {
name: 'GERMANY',
code: 34,
},
},
];
let minItems = items.map(function(item) {
return {
"name": item.name,
"country": {
"name": item.country.name
}
}
});
console.log(minItems);
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.
I have a kids object that looks like the following:
const kids = {
name: 'john',
extra: {
city: 'London',
hobbies: [
{
id: 'football',
team: 'ABC',
},
{
id: 'basketball',
team: 'DEF',
},
],
},
};
and i have the following object that contains all sports and extra info for each.
const sports = [
{
name: 'volleyball',
coach: 'tom',
},
{
name: 'waterpolo',
coach: 'jack',
},
{
name: 'swimming',
coach: 'kate',
},
{
name: 'football',
coach: 'sara',
},
];
I want to get the list of all ids in the hobbies array and go through each of the sports items in the sports array, and found, add an extra field to that object available and give a value of true, so the result will look like:
const result = [
{
name: 'volleyball',
coach: 'tom',
},
{
name: 'waterpolo',
coach: 'jack',
},
{
name: 'swimming',
coach: 'kate',
},
{
name: 'football',
coach: 'sara',
available: true
},
];
by the way, here is my attempt:
const result = kids.extra.hobbies.map(a => a.id);
for (var key in sports) {
console.log(sports[key].name);
const foundIndex = result.indexOf(sports[key].name);
if ( foundIndex > -1) {
sports[key].available = true;
}
}
console.log(sports)
but this is too long... i am looking one liner looking code and robust logic.
This can be done many ways; however, an easy was is to divide the problem into two steps:
We can first flatten the kid's hobbies into an array by using the Array.map() function:
const hobbies = kids.extra.hobbies.map(hobby => hobby.id);
Then, we can iterate through the sports array and add an active property to any object which is present in the new hobbies array:
const result = sports.map(sport => {
if (hobbies.indexOf(sport.name) !== -1) {
sport.available = true;
}
return sport;
})
Complete Solution
const kids = {
name: 'john',
extra: {
city: 'London',
hobbies: [{
id: 'football',
team: 'ABC',
},
{
id: 'basketball',
team: 'DEF',
},
],
},
};
const sports = [{
name: 'volleyball',
coach: 'tom',
},
{
name: 'waterpolo',
coach: 'jack',
},
{
name: 'swimming',
coach: 'kate',
},
{
name: 'football',
coach: 'sara',
},
];
const hobbies = kids.extra.hobbies.map(hobby => hobby.id);
const result = sports.map(sport => {
if (hobbies.indexOf(sport.name) !== -1) {
sport.available = true;
}
return sport;
})
console.log(result);
Firstly, I would change my data structures to objects. Any time you have a list of things with unique ids, objects will make your life much easier than arrays. With that in mind, if you must use arrays, you could do the following:
const hobbies = kids.extra.hobbies
sports.forEach(s => s.available = hobbies.some(h => h.id === s.name))
Note that this mutates the original sports object (change to map for new), and also adds false/true instead of just true.
Build an array of the found sports first, then map while checking to see if the sports object's name is in it:
const kids = {name:'john',extra:{city:'London',hobbies:[{id:'football',team:'ABC',},{id:'basketball',team:'DEF',},],},}
const sports = [{name:'volleyball',coach:'tom',},{name:'waterpolo',coach:'jack',},{name:'swimming',coach:'kate',},{name:'football',coach:'sara',},];
const sportsInHobbies = kids.extra.hobbies.map(({ id }) => id);
const result = sports.map((sportObj) => {
const available = sportsInHobbies.includes(sportObj.name);
return available ? {...sportObj, available } : { ...sportObj };
});
console.log(result);