JavaScript: format CSV array to Json format - javascript

I have the following array which I have extracted from csv file
array
[
{ "Date;Department;Value": "2022-09-08;dept1;7856"},
{ "Date;Department;Value": "2022-09-08;dept2;9876"}
]
I need the following output:
[
{
"Date":"2022-09-08",
"Department":"dept1",
"Value":7856
},
{
"Date":"2022-09-08",
"Department":"dept2",
"Value":9876
}
]

That's quite doable, just take the problem step by step:
const array = [
{ "Date;Department;Value": "2022-09-08;dept1;7856" },
{ "Date;Department;Value": "2022-09-08;dept2;9876" }
];
const result = array
.map(Object.entries) // Convert the objects to more easily accessible arrays.
.map(([[k, v]]) => { // Grab the key / value strings
const keys = k.split(';'); // Split the keys into separate entries.
const values = v.split(';'); // Split the values into separate entries.
// Join the array of keys with the array of values, parsing numbers if possible.
return keys.reduce((obj, key, i) => {
obj[key] = isNaN(values[i]) ? values[i] : Number(values[i]);
return obj;
}, {});
});
console.log(result);

Related

Convert array in JSON file to string

Here's a snippet of my JSON object (EDITED) -
[{
"traditional": "%",
"simplified": "%",
"referencedTraditional": [],
"referencedSimplified": [],
"pinyinNumeric": "pa1",
"pinyinDiacritic": "pā",
"definitions": [
"percent (Tw)"
],
"definitionsDiacritic": [
"percent (Tw)"
]
},
{
"traditional":"龠","simplified":"龠","referencedTraditional":[{"cp":"9fa0","c":"龠"}],"referencedSimplified":[{"cp":"9fa0","c":"龠"}],"pinyinNumeric":"yue4","pinyinDiacritic":"yuè","definitions":["ancient unit of volume (half a 合[ge3], equivalent to 50ml)","ancient flute"],"definitionsDiacritic":["ancient unit of volume (half a 合[gě], equivalent to 50ml)","ancient flute"]},
{"traditional":"龡","simplified":"龡","referencedTraditional":[{"cp":"9fa1","c":"龡"}],"referencedSimplified":[{"cp":"9fa1","c":"龡"}],"pinyinNumeric":"chui4","pinyinDiacritic":"chuì","definitions":["to blow (a flute)","archaic version of 吹"],"definitionsDiacritic":["to blow (a flute)","archaic version of 吹"]},
]
I want to convert every key called definitions from an array into a string.
E.g. From ["percent (Tw)"] to "percent (Tw)". Basically, I don't want the array brackets.
So far, I've tried looping through the file and converting every "definitions" key with JSON.stringify() or toString() -
translations.forEach(key => JSON.stringify((key.definitions)))
However, nothing changes in the outputted file.
Issue with the code is the one below
translations.forEach(key => JSON.stringify((key.definitions)))
Simply running this statement will not update the value for the key inside that object. You have to update the object for this.
Logic.
Loop through the keys in the object translations. I used Object.entries(translations).forEach for that.
Check each key, whether it includes "definitions" in that key.
If the key has "definitions" in that, run your stringification logic. I prefer Array.join() compared to JSON.stringify.
Update the key of that object.
Working Fiddle
const translations = {
"traditional": "%",
"simplified": "%",
"referencedTraditional": [],
"referencedSimplified": [],
"pinyinNumeric": "pa1",
"pinyinDiacritic": "pā",
"definitions": [
"percent (Tw)"
],
"definitionsDiacritic": [
"percent (Tw)"
]
}
Object.entries(translations).forEach(([key, value]) => key.includes('definitions') ? translations[key] = translations[key].join("") : null);
console.log(translations);
const obj = {
traditional: '%',
simplified: '%',
referencedTraditional: [],
referencedSimplified: [],
pinyinNumeric: 'pa1',
pinyinDiacritic: 'pā',
definitions: ['percent (Tw)'],
definitionsDiacritic: ['percent (Tw)'],
};
const returnStringDefinitions = (obj) => {
const arr = [];
for (const [key, value] of Object.entries(obj)) {
if (key === 'definitions') arr.push(value.toString());
}
return arr;
};
console.log(returnStringDefinitions(obj));
I think what may be happening for you is that you aren't saving the resulting array anywhere. The approach could be to create a new object.
const obj = {
traditional: '%',
simplified: '%',
referencedTraditional: [],
referencedSimplified: [],
pinyinNumeric: 'pa1',
pinyinDiacritic: 'pā',
definitions: ['percent (Tw)'],
definitionsDiacritic: ['percent (Tw)'],
};
const output = Object.keys(obj).reduce((accumulator, currentKey) => {
const currentValue = obj[currentKey];
if (currentKey === 'definitions' && Array.isArray(currentValue)) {
accumulator[currentKey] = currentValue.join('');
} else {
accumulator[currentKey] = currentValue;
}
return accumulator;
}, {})
console.log(output);
This solution checks if it is an array, and also just joins everything in the array just in case there are multiple things in the array, but how this is handled is really up to you :)

Filter an array of objects, by keys in filter object

i'm new here, i have problem that i can not solve.
I have 2 different arrays:
The first array - contains ratings of users with their ID name
[
{"handle":"frontend1", "_redis":"3", "_nodejs":"5", "_mysql":"2", "_python":"3", "_mongo":"4"},
{"handle":"frontend3", "_php":"4", "_mysql":"4", "_oracle":"4", "_ruby":"3", "_mongo":"5", "_python":"5"},
{"handle":"frontend4", "_java":"5", "_ruby":"5", "_mysql":"5", "_mongo":"5"}
]
The second set - contains the ratings, which I want to return to each user.
If there is a rating that is not in the second set, I will not return it
In the second set, values do not matter, only keys
[
"_assembler",
"_css",
"_python",
"_php"
]
I want to return to the first set, the handle, and all the rankings that exist in the second set.
[
{"handle":"frontend1", "_python":"3" },
{"handle":"frontend3", "_php":"4", "_python":"5" },
{"handle":"frontend4"}
]
this is what i try to do.
keys = [
"_assembler",
"_css",
"_python",
"_php"
]
source = [
{"handle":"frontend1", "_redis":"3", "_nodejs":"5", "_mysql":"2", "_python":"3", "_mongo":"4"},
{"handle":"frontend3", "_php":"4", "_mysql":"4", "_oracle":"4", "_ruby":"3", "_mongo":"5", "_python":"5"},
{"handle":"frontend4", "_java":"5", "_ruby":"5", "_mysql":"5", "_mongo":"5"}
];
result = [];
tmp = {};
source.forEach((item) => {
Object.keys(item).map(({key,value}) =>
{
if(key == "handle")
{
tmp[key]=value;
}
if(keys.includes(key))
{
tmp[key]=value;
}
})
result.push(...tmp);
tmp = {};
});
You can do this with a map utilizing a couple of other array methods such as filter, and Object methods.
const keys = [
"_assembler",
"_css",
"_python",
"_php"
]
const source = [
{"handle":"frontend1", "_redis":"3", "_nodejs":"5", "_mysql":"2", "_python":"3", "_mongo":"4"},
{"handle":"frontend3", "_php":"4", "_mysql":"4", "_oracle":"4", "_ruby":"3", "_mongo":"5", "_python":"5"},
{"handle":"frontend4", "_java":"5", "_ruby":"5", "_mysql":"5", "_mongo":"5"}
];
const result = source.map( s => ({
handle: s.handle,
...Object.fromEntries(Object.entries(s).filter(x => x[0] != "handle" && keys.includes(x[0])))
}));
console.log(result);

Javascript - how to loop through dict inside a list

So I am pretty new when it comes to Javascript and it is as simple as read a json list with a value of:
{
"URL": [{
"https://testing.com/en/p/-12332423/": "999"
}, {
"https://testing.com/en/p/-123456/": "123"
},
{
"https://testing.com/en/p/-456436346/": "422"
}
]
}
What I would like to do is to have both the URL and the amount of numbers etc
"https://testing.com/en/p/-12332423/" and "999"
and I would like to for loop so it runs each "site" one by one so the first loop should be
"https://testing.com/en/p/-12332423/" and "999"
second loop should be:
"https://testing.com/en/p/-123456/" and "123"
and so on depending on whats inside the json basically.
So my question is how am I able to loop it so I can use those values for each loop?
As Adam Orlov pointed out in the coment, Object.entries() can be very useful here.
const URLobj = {
"URL": [{
"https://testing.com/en/p/-12332423/": "999"
}, {
"https://testing.com/en/p/-123456/": "123"
},
{
"https://testing.com/en/p/-456436346/": "422"
}
]
};
URLobj.URL.forEach(ob => {
console.log('ob', ob);
const entries = Object.entries(ob)[0]; // 0 just means the first key-value pair, but because each object has only one we can just use the first one
const url = entries[0];
const number = entries[1];
console.log('url', url);
console.log('number', number);
})
You mean something like this using Object.entries
const data = {
"URL": [
{"https://testing.com/en/p/-12332423/": "999"},
{"https://testing.com/en/p/-123456/": "123"},
{"https://testing.com/en/p/-456436346/": "422"}
]
}
data.URL.forEach(obj => { // loop
const [url, num] = Object.entries(obj)[0]; // grab the key and value from each entry - note the [0]
console.log("Url",url,"Number", num); // do something with them
})
let's call your object o1 for simplicity. So you can really go to town with this link - https://zellwk.com/blog/looping-through-js-objects/
or you can just use this code :
for(var i = 0; i < o1.URL.length; i++) {
//each entry
var site = Object.keys(URL[i]) [0];
var value = Object.values(URL[i]) [0];
// ... do whatever
}
don't forget each member of the array is an object (key : value) in its own right
You can extract the keys and their values into another object array using map
Then use the for loop on the newly created array. You can use this method on any object to separate their keys and values into another object array.
const data = {
"URL": [{
"https://testing.com/en/p/-12332423/": "999"
}, {
"https://testing.com/en/p/-123456/": "123"
},
{
"https://testing.com/en/p/-456436346/": "422"
}
]
}
var extracted = data.URL.map(e => ({
url: Object.keys(e)[0],
number: Object.values(e)[0]
}))
extracted.forEach((e) => console.log(e))

how can I generate every combination of key/value from a json array?

i have a random json array of key,values where the values are arrays like so:
json = {foo:[1,2],bar:[3,4],pi:[5]}
how can I generate every combination of those parameters for any number of keys so I get back a list like:
{foo:1,bar,3,pi:5}
{foo:1,bar:4,pi:5}
{foo:2,bar:3,pi:5}
{foo:2,bar:4,pi:5}
Use reduce and for each iteration, generate the new permutations:
const json = {foo:[1,2],bar:[3,4],pi:[5, 7], test: [1]};
const results = Object.keys(json).reduce((acc, key) => {
const newArray = [];
json[key].forEach(item => {
if (!acc || !acc.length) { // First iteration
newArray.push({[key]: item});
} else {
acc.forEach(obj => {
newArray.push({...obj, [key]: item});
});
}
});
return newArray;
}, []);
console.log(results);

Combine JavaScript array with multiple sub-values (Node.js / NVD3)

I'm trying to setup a Node.js API that sends JSON data to the client for use in an NVD3 chart. The chart accepts JSON input in the following format:
[
{
"key”:”KEY NAME“,
"values":[
[
1138683600000,
14.212410956029
],
[
1141102800000,
13.973193618249
]
]
},
{
"key”:”KEY NAME“,
"values":[
[
1138683600000,
7.1590087090398
],
[
1141102800000,
7.1297210970108
]
]
}
]
However, my Node program currently outputs JSON in this format:
[
{
"key”:”SAME KEY NAME”,
"values":[
1510148301000,
34
]
},
{
"key”:”SAME KEY NAME”,
"values":[
1509626301000,
55
]
},
{
"key”:”SAME KEY NAME“,
"values":[
1509539901000,
62
]
},
{
"key”:”DIFFERENT KEY NAME“,
"values":[
1509453501000,
58
]
}
]
I want to combine any "key" indices that are the same as other ones and merge the "values" with one another in the specified format. I searched all over to find a way to do this, but each method I came across didn't account for multiple pairings within the "value" index.
Any suggestions on how I could do this?
Thanks!
You can use Array.prototype.reduce to accumulate the items from your original array into an object keyed uniquely by the item's key-value. Since this leaves you with an Object instead of an array, you can then use Object.values to spit out the array of values like your example output.
let data = [
{"key":"A", "values":[1510148301000, 34]},
{"key":"A", "values":[1509626301000, 55]},
{"key":"A", "values":[1509539901000, 62]},
{"key":"B", "values":[1509453501000, 58]},
{"key":"B", "values":[1509453501001, 57]},
];
let combined = Object.values(data.reduce((accumulator, item) => {
if (!accumulator[item.key])
accumulator[item.key] = {key: item.key, values: []};
accumulator[item.key].values.push(item.values);
return accumulator;
}, {}));
console.log(combined);
I'm not sure about what you want (merge?), but it seems to be like that:
function combine (obj) {
var combined = {}
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
if (!!combined[key]) {
combined[key] = [].concat(combined[key], obj[key].values) // everything in one
// or
// combined[key].push(obj[key].values) // everything in distinct arrays
} else {
combined[key] = obj[key].values
// or
// combined[key] = [obj[key].values] // in distinct arrays
}
}
}
return combined
}
var original=[{"key":"SAME KEY NAME","values":[1510148301000,34]},{"key":"SAME KEY NAME","values":[1509626301000,55]},{"key":"SAME KEY NAME","values":[1509539901000,62]},{"key":"DIFFERENT KEY NAME","values":[1509453501000,58]}];
var result=[];
var isAlreadyAdded=false;
original.forEach(function(outerObj){
var newObj={};
var values=[];
original.forEach(function(element) {
if(newObj["key"] !== outerObj.key){
newObj["key"]=element.key;
values=[];
values.push(element["values"]);
}else if(outerObj.key ===element.key ){
values.push(element["values"]);
}
});
newObj["values"]=values;
var count=0;
result.push(newObj);
});
var temp=[];
result=result.filter((x, i)=> {
if (temp.indexOf(x.key) < 0) {
temp.push(x.key);
return true;
}
return false;
})
console.log(result);

Categories