How to map value to key? - javascript

Map will not accept dot notation for a key, how would you map a key from an array of objects to a key in a new object? For example I would like to convert:
this
searchResults = [{ _id: 'qEJBC9gED8knEKhHF',
key: 'key1',
value: 1 },
{ _id: 'KeoMTbpuCeuQMH8LJ',
key: 'key2',
value: 5 },
{ _id: 'Foy5pXbDbtLABmCxC',
key: 'key3',
value: 4 }
]
to this
[{ _id: 'qEJBC9gED8knEKhHF',
key1: 1 },
{ _id: 'KeoMTbpuCeuQMH8LJ',
key2: 5 },
{ _id: 'Foy5pXbDbtLABmCxC',
key3: 4 }]
Example that does not work...
get_settings = function(doc) {
return {
doc.key: doc.value
}
};
currentUserSettings = searchResults.settings.map(get_settings);

You can achieve this with JS Array.Map prototype
Just use square brackets and pass in the value.
var data = [{
_id: 'qEJBC9gED8knEKhHF',
key: 'key1',
value: 1
},
{
_id: 'KeoMTbpuCeuQMH8LJ',
key: 'key2',
value: 5
},
{
_id: 'Foy5pXbDbtLABmCxC',
key: 'key3',
value: 4
}
]
var mappedData = data.map(function(item) {
return {
_id: item._id,
[item.key]: item.value
}
});
console.log(mappedData)

Related

How to spread inner object

I have data like this
finalValue [
{ _id: { _id: 'OUTCOME_APPROUVED' }, count: 1 },
{ _id: { _id: 'OUTCOME_SWITCH_INTERFACE' }, count: 5 }
]
I want to spread the inner object and change the keys to name and value to make final value looks like this
finalValue [
{ name: 'OUTCOME_APPROUVED' , value: 1 },
{ name: 'OUTCOME_SWITCH_INTERFACE' , value: 5 }
]
try this :
var finalValue = [
{ _id: { _id: 'OUTCOME_APPROUVED' }, count: 1 },
{ _id: { _id: 'OUTCOME_SWITCH_INTERFACE' }, count: 5 }
]
var newValue = finalValue.map(({_id:{_id},count}) => {
return {name:_id , value:count}
})
console.log(newValue)
[JS]
You could use map instead of spreading, and not sure about how you could spread it to format it the way you want.
const inputValue = [ { _id: { _id: 'OUTCOME_APPROUVED' }, count: 1 },
{ _id: { _id: 'OUTCOME_SWITCH_INTERFACE' }, count: 5 }]
const computedValue = inputValue.map((data) => {
return { name: data._id._id, value: data.count };
});

Transform Object attribute to array of object

I want to merge Array of ObjectA containing ObjectB attribute by ObjectA attribute.
For example :
let myArray = [
{ name: 'Jeu', series: { name: 'testA', value: '89' } },
{ name: 'Dim', series: { name: 'testB', value: '490' } },
{ name: 'Dim', series: { name: 'testC', value: '978' } }
]
And I would like to transform it to
[
{ name: 'Jeu', series: { name: 'testA', value: '89' } },
{ name: 'Dim', series: [{ name: 'testB', value: '490' },{ name: 'testC', value: '978' } ] }
]
Am I able to do that with a simple reduce/map loop ?
You can first use reduce (with some spread syntax) to build an object that maps unique names and objects in the format you want to have, grouping series by name. Then, you can simply get the values from this object.
const myArray = [
{ name: 'Jeu', series: { name: 'testA', value: '89' } },
{ name: 'Dim', series: { name: 'testB', value: '490' } },
{ name: 'Dim', series: { name: 'testC', value: '978' } }
];
const map = myArray.reduce(
(acc, curr) => ({
...acc,
[curr.name]: {
name: curr.name,
series: acc[curr.name]
? [...acc[curr.name].series, curr.series]
: [curr.series]
}
}),
{}
);
const output = Object.values(map);
console.log(output);

Transforming array of objects based upon key - javascript

I am trying to figure out the most efficient method for reducing an array of objects based upon a unique key (key/values are dynamically returned in this case). I've tried to a combination of different methods using concat, map, or filter but haven't had much luck.
Original array of objects:
[
{
key: "Name",
value: "John"
},
{
key: "Company",
value: "Acme"
},
{
key: "Name",
value: "Jack"
},
{
key: "Name",
value: "Matt"
},
{
key: "Last",
value: "Test"
}
]
Desired Array:
[
{
key: "Name",
values: [
"John",
"Jack",
"Matt"
]
},
{
key: "Company",
values: [
"Acme"
]
},
{
key: "Last",
values: [
"Test"
]
}
]
Prob other ways, but a simple for loop would suffice:
const data = [{
key: "Name",
value: "John"
},
{
key: "Company",
value: "Acme"
},
{
key: "Name",
value: "Jack"
},
{
key: "Name",
value: "Matt"
},
{
key: "Last",
value: "Test"
}
]
let result = {}
for (const i in data) {
result[data[i].key] = {
key: data[i].key,
values: [
...result[data[i].key] ? result[data[i].key].values : [],
data[i].value
]
}
}
console.log(Object.values(result))
You can use reduce to build a new object using name as the keys, and then use Object.values to create the output you need from the object:
const data = [
{ key: "Name", value: "John" },
{ key: "Company", value: "Acme" },
{ key: "Name", value: "Jack" },
{ key: "Name", value: "Matt" },
{ key: "Last", value: "Test" }
];
const out = Object.values(data.reduce((acc, { key, value }) => {
// If the key doesn't exist on the object, add it
// and initialise the value object
acc[key] = acc[key] || { key, values: [] };
// Push the value from the current iteration
// into the values array
acc[key].values.push(value);
// Return the accumulator for the next iteration
return acc;
}, {}));
console.log(out);
I think reduce is the best solution here :)
const initialArray = [
{
key: "Name",
value: "John"
},
{
key: "Company",
value: "Acme"
},
{
key: "Name",
value: "Jack"
},
{
key: "Name",
value: "Matt"
},
{
key: "Last",
value: "Test"
}
];
const result = initialArray.reduce((acc, obj) => {
/* try to find object in the result array
returns index or -1 if object is missing
*/
const existingIndex = acc.findIndex(item => item.key === obj.key);
if (existingIndex > -1) {
/* object already exists, update its values array */
acc[existingIndex].values.push(obj.value);
return acc;
} else {
/* the key is first encountered, create an object in the result array */
acc.push({
key: obj.key,
values: [obj.value],
});
return acc;
}
}, []); // [] - default value is an empty array
console.log(result);

Transform the data

I have the following data structure:
const data = [
{
name: 'ABC',
salesData: [
{
timestamp: '2017-09-01',
value: 10
},
{
timestamp: '2017-09-02',
value: 2
}
]
},
{
name: 'DEF',
salesData: [
{
timestamp: '2017-09-01',
value: 8
},
{
timestamp: '2017-09-02',
value: 3
}
]
}
];
I would like to transform this to:
[
{
name: 'ABC',
'2017-09-01': 10,
'2017-09-02': 2
},
{
name: 'CDE',
'2017-09-01': 8,
'2017-09-02': 3
}
]
I'm trying to use Underscore's Chain and Map which I'm getting confused. So far I have the following, not sure how do I write the convertedSalesData to transform as per the need:
_.map(data, function(item) {
let name = item.name;
let salesData = item.salesData;
let convertedSalesData = ?
})
With ES6 you can use spread syntax ... to get this result.
const data = [{"name":"ABC","salesData":[{"timestamp":"2017-09-01","value":10},{"timestamp":"2017-09-02","value":2}]},{"name":"DEF","salesData":[{"timestamp":"2017-09-01","value":8},{"timestamp":"2017-09-02","value":3}]}]
var result = data.map(function({name, salesData}) {
return {name, ...Object.assign({}, ...salesData.map(({timestamp, value}) => ({[timestamp]: value})))}
})
console.log(result)
const data = [{
name: 'ABC',
salesData: [{
timestamp: '2017-09-01',
value: 10
},
{
timestamp: '2017-09-02',
value: 2
}
]
},
{
name: 'DEF',
salesData: [{
timestamp: '2017-09-01',
value: 8
},
{
timestamp: '2017-09-02',
value: 3
}
]
}
];
var res = data.map(function(a) {
var obj = {
name: a.name
};
a.salesData.forEach(function(x) {
obj[x.timestamp] = x.value;
})
return obj;
})
console.log(res);
Similar to #Nenad Vracar. I perfer to use 'reduce':
data.map(({ name, salesData }) => ({
name,
...salesData.reduce(
(record, { timestamp, value }) => {
record[timestamp] = value
return record
},
Object.create(null)
)
}))

Concat array from Object from Array

I'm currently trying to retrieve a list of metadata stored as an array, inside an object, inside an array. Here's a better explanatory example:
[
{
name: 'test',
metadata: [
{
name: 'Author',
value: 'foo'
},
{
name: 'Creator',
value: 'foo'
}
]
},
{
name: 'otherTest',
metadata: [
{
name: 'Created',
value: 'foo'
},
{
name: 'Date',
value: 'foo'
}
]
},
{
name: 'finalTest'
}
]
Now, my objective is to retrieve a list of metadata (by their name) without redundancy. I think that .map() is the key to success but I can't find how to do it in a short way, actually my code is composed 2 for and 3 if, and I feel dirty to do that.
The expected input is: ['Author', 'Creator', 'Created', 'Date']
I'm developping in Typescript, if that can help for some function.
You can use reduce() and then map() to return array of names.
var data = [{"name":"test","metadata":[{"name":"Author","value":"foo"},{"name":"Creator","value":"foo"}]},{"name":"otherTest","metadata":[{"name":"Created","value":"foo"},{"name":"Date","value":"foo"}]},{"name":"finalTest"}]
var result = [...new Set(data.reduce(function(r, o) {
if (o.metadata) r = r.concat(o.metadata.map(e => e.name))
return r
}, []))];
console.log(result)
You could use Set for unique names.
var data = [{ name: 'test', metadata: [{ name: 'Author', value: 'foo' }, { name: 'Creator', value: 'foo' }] }, { name: 'otherTest', metadata: [{ name: 'Created', value: 'foo' }, { name: 'Date', value: 'foo' }] }, { name: 'finalTest' }],
names = new Set;
data.forEach(a => (a.metadata || []).forEach(m => names.add(m.name)));
console.log([...names]);
.as-console-wrapper { max-height: 100% !important; top: 0; }
var data = [{"name":"test","metadata":[{"name":"Author","value":"foo"},{"name":"Creator","value":"foo"}]},{"name":"otherTest","metadata":[{"name":"Created","value":"foo"},{"name":"Date","value":"foo"}]},{"name":"finalTest"}]
data
.filter(function(obj){return obj.metadata != undefined})
.map(function(obj){return obj.metadata})
.reduce(function(a,b){return a.concat(b)},[])
.map(function(obj){return obj.name})
A hand to hand Array.prototype.reduce() and Array.prototype.map() should do it as follows;
var arr = [
{
name: 'test',
metadata: [
{
name: 'Author',
value: 'foo'
},
{
name: 'Creator',
value: 'foo'
}
]
},
{
name: 'otherTest',
metadata: [
{
name: 'Created',
value: 'foo'
},
{
name: 'Date',
value: 'foo'
}
]
},
{
name: 'finalTest'
}
];
result = arr.reduce((p,c) => c.metadata ? p.concat(c.metadata.map(e => e.name))
: p, []);
console.log(result);

Categories

Resources