I have the following Json Object
[
{ "key": "age", "value": 81 },
{ "key": "name", "value": "Luis" }
]
I am trying to find the most optimal way to recover this data.
const name = ??????;
What's the best way to extract the "value" of the 'name' key using Javascript? I know one of the ways would be to iterate until I find the value, but I figured there is a more fancy way, perhaps using filter?
Luis
I am assuming you need the object that has key as name
You can get use of find method
let array = [
{ "key": "age", "value": 81 },
{ "key": "name", "value": "Luis" }
]
let your_obj = array.find(element=>element.key === 'name')
console.log(your_obj) // this will give you the object you need
This will give results with key name
names = [
{ "key": "age", "value": 81 },
{ "key": "name", "value": "Luis" }
]
result = names.filter(name => name.key === 'name')
Related
I have an array of objects like,
customer1 = [
{"key": "name",
"value": "Peter"},
{"key": "age",
"value": 23},
{"key": "address",
"value": "xyz St, abcd"},
{"key": "points",
"value": 234}
]
and I want to find say age and address from this object, what is the recommended and optimal way to do that? For real application, I might have 20-40 key-value objects in this array, out of which I might want to access 5-10 values.
What I do right now is I loop through this object and use conditions to find and assign values to my variables. but in this approach, I have to write multiple else if expressions (5-10).
For example,
let name: string;
let points: number;
for (var item of customer1) {
if (item.key === "name") {
name = item.value;
} else if (item.key === "points") {
points = item.value;
}};
You can simply achieve this requirement with the help of Array.filter() along with Array.map() method.
Live Demo :
const customer1 = [
{ "key": "name", "value": "Peter" },
{ "key": "age", "value": 23 },
{ "key": "address", "value": "xyz St, abcd" },
{ "key": "points", "value": 234 }
];
const searchKeys = ['age', 'address'];
const res = customer1.filter(obj => searchKeys.includes(obj.key)).map(({ value}) => value);
const [age, address] = res;
console.log(age);
console.log(address);
You will always have to write explicitly "name", "points",... because you can't parse string value and use it to identify variable with the same name.
But to avoid using multiple else if, maybe the switch case statement is more appropriate and readable?
interface CustomerProperty {
key: string,
value: string | number
}
let customer1: CustomerProperty[] = [
{
"key": "name",
"value": "Peter"
},
{
"key": "age",
"value": 23},
{
"key": "address",
"value": "xyz St, abcd"},
{
"key": "points",
"value": 234
}
];
let nameValue: string;
let pointsValue: number;
for (var item of customer1) {
switch (item.key) {
case "name":
nameValue = item.value as string;
break;
case "points":
pointsValue = item.value as number;
break;
}
};
I would like to convert the below array of objects into another form (varname is ignored as its not required, key and value is used to generate the output form). Any leads would be appreciated
Input array:
[
{
"key": "string_U6",
"value": "grandwagoneer",
"varname": "pagenameplate"
},
{
"key": "string_U13",
"value": "2021",
"varname": "year"
}
]
Output
[
{
"string_U6": "grandwagoneer"
},
{
"string_U13": "2021"
}
]
You could try using map as below:
var input = [ { "key": "string_U6", "value": "grandwagoneer", "varname": "pagenameplate" }, { "key": "string_U13", "value": "2021", "varname": "year" } ];
var output = input.map(function(entry){
let obj = {};
obj[entry.key] = entry.value;
return obj;
});
console.log(output);
As the question asked how to convert array object in snowflake, I wanted to share Snowflake way to do it:
-- SQL to create a sample table with data
create table sample_table (v variant )
as select parse_json(' [ { "key": "string_U6", "value": "grandwagoneer", "varname": "pagenameplate" },
{ "key": "string_U13", "value": "2021", "varname": "year" } ]');
-- query to parse the variant and create the array:
select ARRAY_AGG( OBJECT_CONSTRUCT(i.value:key::varchar, i.value:value::varchar) )
from sample_table,
lateral flatten ( sample_table.v ) i;
It will produce exact output you want.
I have a JSON in the following format and need to convert the 2 values into a Key / Value pair in javascript
"column_values": [
{
"id": "status",
"text": "Working on it"
}
]
I need the result to be
"column_values"[{"status": "Working on it"}]
I need the code to iterate through the column_values array and convert all the sets of id and text pairs to the key = id value : Value = text:values
Is my result possible?
Additional Information...
I am parsing a response from monday.com api in zapier.
the api payload is contained in
const results = response.json;
the full api payload is
{
"data": {
"boards": [
{
"name": "Test Board",
"items": [
{
"name": "Name Change",
"id": "625495642",
"column_values": [
{
"id": "person",
"text": ""
},
{
"id": "subitems",
"text": "Subitem 1, Subitem 2"
},
{
"id": "status",
"text": "Working on it"
},
{
"id": "dropdown",
"text": "Test1"
},
{
"id": "formula",
"text": ""
}
]
}
]
}
]
},
"account_id": 1111
}
I need to the the code to parse the data and replace the column_values with the format above, and then pass the reformated payload to
return results;
You just Map the Array you start out with to an Array with the values.
var column_values = [ { "id": "status", "text": "Working on it" } ]
var KeyValuePairs = column_values.map(cv => [cv.id,cv.text]);
console.log(KeyValuePairs);
If every object is going to contain the id and text keys only, you can map it and delete the other keys.
column_values = column_values.map(item => {
item[item.id] = item.text;
delete item.id;
delete item.text;
return item;
});
try this
var column_values = [ { "id": "status", "text": "Working on it" } ]
var res = column_values.map(x => ({[x.id] : x.text}))
console.log(res)
Summary
I receive a large JSON object in node--about 10000 lines--from an external API and I'm creating a new, consolidated javascript object with the data I want.
I'm extracting specific key:value pairs from an object, where another key:value pair in the object matches what I'm looking for. The main issue I'm having is that if there is no data for a specific object, that object is not included and the function I wrote to assign the specific data I want to a variable becomes undefined and crashed my node server.
**Example API Response (Abbreviated) **
I commented on the data I'm trying to extract
{
"ApiJSONObject": {
"id": "t4365qewsagsdga4",
"stats": [{
"metadata": {
"key": "kills",
"name": "Kills",
"isReversed": false
},
"value": 6435, //Extract this value and save to specific key in new javascript object
"displayValue": "6,435"
}
],
"segments": [{
"metadata": [{
"key": "segment",
"name": "Segment",
"value": "br.close_solo.season",
"displayValue": null
},
{
"key": "lastPlayedAt",
"name": "Last Played At",
"value": "2018-12-11T16:46:35Z",
"displayValue": "12/11/18 4:46:35 PM"
},
{
"key": "updatedAt",
"name": "Updated At",
"value": "2019-06-10T19:07:00.9143166Z",
"displayValue": "6/10/19 7:07:00 PM"
}
],
"stats": [{
"metadata": {
"key": "kills",
"name": "Kills",
"isReversed": false
},
"value": 1, //extract this value and save to specific key in new javascript object based on metaData[0].value
"displayValue": "1"
},
{
"metadata": {
"key": "matchesPlayed",
"name": "Matches Played",
"isReversed": false
},
"value": 1,
"displayValue": "1"
}
]
}]
}
}
Current Function
I wrote this function, however it breaks my code as stats is undefined if there is no data for that specific statsSegment
function getSegmentStats(statType, playerStats) {
let filteredMetaData = [];
for (var i = 0; i < playerStats.segments.length; i++) {
filteredMetaData = playerStats.segments[i].metadata.filter(
val => val["value"] === statType
);
if (filteredMetaData.length) {
return playerStats.segments[i];
}
}
}
function getStatsFields(value,"br.close_solo.season") {
const stat = statsSegment.stats.find(x => x.metadata.name === value);
return stat.value;
}
const seasonSolo = getSegmentStats("br.close_solo.season", playerStats);
const statsObject = { seasonStats: seasonSolo: getStatsFields("Kills", seasonSolo))
The simplest solution would be to just check if your statsSegment is undefined at the start of your function, but first you need to decide what you do in case it is undefined.
you have few options:
throw an error
return an "errored" value- 0, false, -1- something that will never get returned as stat.value and you'll know for sure it means an error.
emit an event of some sort (don't know the context you're using this).
To perform the check simply add if(statSegment === undefined) at the start of getStatField function.
Also, i'd suggest you look at the docs for that 3rd party API you're using and see what undefined return value even means.
And one last thing- this API might return an empty object (also, check at the docs), so the undefined test will pass but you still won't be able to process the data. You can add an empty object test as well:
if(statSegment === undefined || (Object.entries(statSegment).length === 0 && statSegment.constructor === Object));
if you're using ECMA 7+, or:
if(statSegment === undefined || (Object.keys(statSegment).length === 0 && statSegment.constructor === Object));
if you're using ECMPA 5+.
(for more info about this empty object check go here)
When .find() can't find anything which matches its inner function's criteria, it will by default return undefined. By using the logical OR operator (||) you can set the value of stat to be a default object which always has a value of 0:
function getStatsFields(value,"br.close_solo.season") {
const stat = statsSegment && statsSegment.stats.find(x => x.metadata.name === value) || {value: 0};
return stat.value;
}
let statsSegmentJson = {
"ApiJSONObject": {
"id": "t4365qewsagsdga4",
"stats": [{
"metadata": {
"key": "kills",
"name": "Kills",
"isReversed": false
},
"value": 6435, //Extract this value and save to specific key in new javascript object
"displayValue": "6,435"
}
],
"segments": [{
"metadata": [{
"key": "segment",
"name": "Segment",
"value": "br.close_solo.season",
"displayValue": null
},
{
"key": "lastPlayedAt",
"name": "Last Played At",
"value": "2018-12-11T16:46:35Z",
"displayValue": "12/11/18 4:46:35 PM"
},
{
"key": "updatedAt",
"name": "Updated At",
"value": "2019-06-10T19:07:00.9143166Z",
"displayValue": "6/10/19 7:07:00 PM"
}
],
"stats": [{
"metadata": {
"key": "kills",
"name": "Kills",
"isReversed": false
},
"value": 1, //extract this value and save to specific key in new javascript object based on metaData[0].value
"displayValue": "1"
},
{
"metadata": {
"key": "matchesPlayed",
"name": "Matches Played",
"isReversed": false
},
"value": 1,
"displayValue": "1"
}
]
}]
}
};
let value = 'Kills';
function getStatsFields(value, statsSegment) {
let statsSegmentStr = JSON.stringify(statsSegment);
let statsSegmentObj = JSON.parse(statsSegmentStr);
console.log("statsSegment", statsSegmentObj);
console.log("statsSegment.stats ", statsSegmentObj.ApiJSONObject.stats);
const stat = statsSegmentObj.ApiJSONObject.stats.find(x => x.metadata.name === value);
if (stat) {
return stat.value;
}
}
let result = getStatsFields(value,statsSegmentJson);
console.log(result);
I have a specific format for a set of JSON objects. The format is as follows:
[{
"key": ["key1"],
"value": ["value1", "value2", "value3"]
}, {
"key": ["key2", "key3"],
"value": ["value4", "value5", "value6"]
}]
I am writing a function using simply JavaScript (no jQuery), that will append a value to the .value element based on if the user input matches a key value. For example, I input key2, the logic will match against key 2, and append "value7" to the end of the value element for that key, resulting in the following:
[{
"key": ["key1"],
"value": ["value1", "value2", "value3"]
}, {
"key": ["key2", "key3"],
"value": ["value4", "value5", "value6", "value7"]
}]
Currently the JSON is just an object in the JS file that is parsed using JSON.parse("string"). I would need to perform the appending and then rebuild the JSON using Stringify. (Assuming that would be my logic). I just need help with the appending because I am confused on the logic in this scenario. If anyone could throw together a quick example of how this would look in JS, that would be a massive help. Thank you!
You't target the object, and then the property containing the array, and push to that array
var array = [{
"key": ["key1"],
"value": ["value1", "value2", "value3"]
}, {
"key": ["key2", "key3"],
"value": ["value4", "value5", "value6"]
}];
array[1].value.push('value7');
console.log(array);
check this snippet
var arr = [{
"key": ["key1"],
"value": ["value1", "value2", "value3"]
}, {
"key": ["key2", "key3"],
"value": ["value4", "value5", "value6"]
}]
console.log(insertAtKey(arr, 2, "value7"));
function insertAtKey(arr, index, str) {
var obj = arr[index - 1];
Object.keys(obj).forEach(function(key, val) {
if (key === "value") {
obj[key].push(str);
}
});
arr[index - 1] = obj;
return arr;
}
Hope it helps
This question sounds like homework to me and I don't want to spoil the whole solution, but you can use a filter for searching in the object array, for adding the value you have the rest of the puzzle:
var data = [{
"key": ["key1"],
"value": ["value1", "value2", "value3"]
}, {
"key": ["key2", "key3"],
"value": ["value4", "value5", "value6"]
}];
function hasKey(k) {
return data.filter(e => { return e['key'].includes(k); });
}
console.log("for key1:" + hasKey("key1")[0].value);
console.log("for key2:" + hasKey("key2")[0].value);
console.log("for key3:" + hasKey("key3")[0].value);
What filter does:
e => { return e['key'].includes(k); } If the current object e in the data array includes a value k in the key attribute then pass the value.