I have an array from an API call.
var response = {
"data": {
"data": [{
"1": "Arun",
"index": "name"
}, {
"1": 70.78,
"index": "score"
}]
}
}
I connect to a lot of other API's and they return me a similar response but the keys change. Sometimes it might be
var response = {
"data": {
"data": [{
"values": "Harry",
"index": "name"
}, {
"values": 45,
"index": "score"
}]
}
}
var response = {
"data": {
"data": [{
"4": "Richard",
"index": "name"
}, {
"4": 98,
"index": "score"
}]
}
}
I would like to get an array like this.
[
{
name: 'Arun',
score: 70.78
}
]
This is what I did.
var response = { "data": { "data": [{ "1": "Arun", "index": "name" }, { "1": 70.78, "index": "score" }] } } const result = []; const mappedData = _.map(response.data.data, (item) => { return { [item.index]: item[1] }; }); const resultObject = _.reduce(mappedData, (result, currentObject) => { for (const key in currentObject) { if (currentObject.hasOwnProperty(key)) { result[key] = currentObject[key]; } } return result; }, {}); result.push(resultObject) console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
So instead of hardcoding "1" or "values" in the map function, is there a more universal way to get the key and achieve the same result?
Thanks.
Use reduce
rather than map
, so you're updating the same object, not creating an array.
And since the property containing the value can vary, I use a loop to look for the first property that isn't named index
, and use its value.
var response = { "data": { "data": [{ "1": "Arun", "index": "name" }, { "1": 70.78, "index": "score" }] } } const mappedData = response.data.data.reduce((acc, item) => { var value; // find the property that isn't named "item" for (var i in item) { if (i != "index") { value = item[i]; break; } } acc[item.index] = value; return acc; }, {}); console.log(mappedData)
There's no need for lodash for this, the built-in reduce
function is fine (but _.reduce
will work similarly).
Since you only care about the values of that object and it only has two keys you can do this quite easily in lodash with reduce & fromPairs :
var response = { "data": { "data": [{ "1": "Arun", "index": "name" }, { "1": 70.78, "index": "score" }] } } const rv = (o) => _.reverse(_.values(o)) const r = _.reduce(response.data.data, (a,c) => _.fromPairs([rv(a), rv(c)])) console.log(r)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
The same thing converted to ES6 would be:
var response = { "data": { "data": [{ "1": "Arun", "index": "name" }, { "1": 70.78, "index": "score" }] } } const rv = (o) => Object.values(o).reverse() // reverse values const fp = (arr) => arr.reduce((r, [k,v]) => (r[k] = v, r), {}) // from pairs const result = response.data.data.reduce((a,c) => fp([rv(a), rv(c)])) console.log(result)
The main idea here is to first get the object values in an array form, reverse them so the key
& value
are in the correct order and then reduce
that array via from pairs
to create the final object.
The main advantage of this approach is that we never deal with the object keys and only focus on the values which is what you really care about. This way the keys can be any value and it would still not matter.
You could try deleting the key-pair index
and using the first value
of the resulting object:
const mappedData = _.map(response.data.data, (item) => {
var tempObj = Object.assign({}, item)
var index = tempObj.index;
delete tempObj.index;
var otherData = Object.values(tempObj)[0];
return {
[index]: otherData
};
});
Just modified the @barmar approach. I have used Object.keys
to get keys from object. This will remove the any hard-coded dependency.
var response = { "data": { "data": [{ "1": "Arun", "index": "name" }, { "1": 70.78, "index": "score" }] } } const mappedData = response.data.data.reduce((acc, item,i) => { var key = Object.keys(item); acc[item[key[1]]] = item[key[0]] return acc ; }, {}); console.log(mappedData)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.