I am using XLSX NPM to read the XLSX file and i converted to json as like below
My Xlsx sheet is of format:..
skill id name xx
abc 4578 express-basic 30
4698 express-advanced 60
qwerty 7856 express-basic 90
MY Json:
[ { skill: 'abc',
id: 4578,
name: 'express-basic',
xx: 30 },
{ id: 4689, name: 'express-advanced', xx: 60 },
{ skill: 'qwerty',
id: 7856,
name: 'express-advanced',
xx: 90 } ]
I have to update collection X where id=4578,4689 ass skill = abc so how can i convert the below json into as follows:
[
{'abc':[4578,4689]},
{'qwerty':[7856]}
]
so that i can loop through this and i can update the collectionX. My problem is how can i know the next skill is starting from the json and construct the Above array. Thanks...
You Can work with array.reduce.
YOUR_JSON_ARRAY.reduce(function (obj, item) {
obj[item.skill] = obj[item.skill] || [];
obj[item.skill].push(item.id);
return obj;
}, {});
Above code will groupBy your Array by using item.skill key.
P.S. you need to handle this if item.skill doesn't exists,
otherwise it will create undefined key:value pair.
Hope it will help.
Related
I'm studying about JSON and its use cases. Suppose I have a recipe book and I have the following JSON to store recipes (I apologize if anything is wrong before hand, I'm just starting with this)
var recipeBook =
{
recipes:
[
{
name: 'Spaghetti',
ingredients:
[
{
ingredientName: 'Pasta',
requiredAmount: 1,
},
{
ingredientName: 'Tomato Sauce',
requiredAmount: 1,
}
]
},
{
name: 'Cereal',
ingredients:
[
{
ingredientName = 'Cereal Box',
requiredAmount = 1
},
{
ingredientName = 'Milk',
requiredAmount = '1'
}
]
}
]
}
Say I wanted to add a third recipe, or add a new ingredient to a recipe...I'm wondering what is the best option (code-wise) to add new data into this JSON.
I think propably the function you are looking for is https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push, for example
recipeBook.recipes.push({
name: 'Soup',
ingredients:
[
{
ingredientNam: 'Water',
requiredAmount: 1
},
{
ingredientName: 'Potatoes',
requiredAmount: 4
}
]
})
And for new ingredients it would be
recipeBook.recipes[0].ingredients.push(
{
ingredientName: 'Salt',
requiredAmount: 1
}
)
I would recomend you to use the name of the recipe as the key in the recipes, I mean:
var recipeBook =
{
recipes:
{
Spaghetti:
{
ingredients:
[
{
ingredientName: 'Pasta',
requiredAmount: 1,
},
{
ingredientName: 'Tomato Sauce',
requiredAmount: 1,
}
]
},
Cereal:
{
ingredients:
[
{
ingredientName: 'Cereal Box',
requiredAmount: 1
},
{
ingredientName: 'Milk',
requiredAmount: 1
}
]
}
}
}
This helps to get the recipe as
var spaghettiRecipe = recipeBook.recipes.Spaghetti
First, JSON vs. JS Objects
JSON isn't to be confused with generic objects in JavaScript. JSON is a "lightweight data-interchange format" that does its best to be both easy for humans to read and edit, yet also easy for computers to parse and generate. One of the main differences is that JSON has stricter syntax requirements than generic JS objects do.
What you've written is simply an object declaration in Javascript, rather than standard JSON. A JSON equivalent to your example data would look like this:
{
"recipes": [
{
"name": "Spaghetti",
"ingredients": [
{
"ingredientName": "Pasta",
"requiredAmount": 1
},
{
"ingredientName": "Tomato Sauce",
"requiredAmount": 1
}
]
},
{
"name": "Cereal",
"ingredients": [
{
"ingredientName": "Cereal Box",
"requiredAmount": 1
},
{
"ingredientName": "Milk",
"requiredAmount": 1
}
]
}
]
}
The specific distinctions here:
All property names are enclosed in double quotes "
All strings are enclosed in double quotes " rather than single '
Trailing commas that aren't followed by another key/ value pair or data structure aren't allowed
You could choose to omit the recipes property and keep just the array without the enclosing object, this would still be valid.
Also worth noting that prop = value is not allowed in either syntax, JS object declaration nor JSON.
A description of the full JSON spec is here if you're interested.
Manipulating JS Data
You asked what the best option code-wise is to add data to this JSON. Since JSON is just a format, it's not actually super relevant here, since it's primarily used for data storage and transport, and not for manipulation.
To work with data stored as JSON in Javascript, you can parse it in with the JSON.parse(string) method, which will read a JSON string and return an equivalent Javascipt object. You can then use standard object/ array manipulation methods and techniques on that resulting object, in this case using push() to add a new recipe onto the array.
Here is some sample code to add data to the object
//add recipe
recipeBook.recipes.push(newRecipe);
//add ingredient to recipe by name
var recipe = recipeBook.recipes.find(r => r.name == recipeName);
if (recipe) recipe.ingredients.add(newIngredient);
Also your Cereal object is using ingredientName = 'Cereal Box', which is invalid javascript syntax. You need to use : as in your spaghetti object.
Instantiating an object involves creating an object programmatically. I'm simplifying the code to make it easy:
var book = {}
function Recipe(name, ingredients) {
this.name = name;
this.ingredients = ingredients;
}
// instantiate it
var chicken_teriyaki = new Recipe('Teriyaki', ['new one', 'two', 'three'])
var fried_chicken = new Recipe('Fried Chicken', ['chicken', 'potato starch', 'oil'])
// add to book
book.chicken_teriyaki = chicken_teriyaki;
book.fried_chicken = fried_chicken;
// update recipe
book.chicken_teriyaki.ingredients.push('another yummy')
// view result
console.log('the book', book);
I'm using Node (https://eemeli.org/yaml/) to parse a YAML configuration files which looks like so:
items:
- name: item 1
value: 25
- name: item 2
value: 25
- name: item 3
value: 50
What I'd like to do is assert the value numbers all add up to 100 when parsing the document.
Should I be running this validation after parsing the YAML
eg:
data = YAML.parse(recipe)
validate(data)
Or is there a better way of doing this using the YAML library directly when loading the document?
Thanks in advance for your help!
You're better of parsing the YAML first, then going through the resulting data. So, in this case, the parsed data would look something like:
data = {
items: [
{name: 'item 1', value: 25},
{name: 'item 2', value: 25},
...
]
}
So, you can just loop through the values:
let total = 0;
data.items.map((item) => {
total += item.value;
});
if (total !== 100) {
...
}
Is it possible to use a JavaScript object as a type of mini database? I often find myself needing a kind of database structure when I'm coding in JS but it feels like overkill to use an actual database like MySQL (or similar).
As an example, let's say I need to structure this data as a JS object:
Object idea: Stuff to sell
Items to sell: The junk in the garage
Object structure: List all items including item name, item condition, and item value
In order to make this into a JS object I would maybe write:
var stuffToSell = {};
Then my first item would maybe look like:
var stuffToSell = {
item : "Coffee Maker",
condition : "Good",
price : 5
};
Now to me this seems like I'm on the right track, until I come to add another item and I end up having to use the properties item, condition, and price again in the same JS object — which feels wrong? — or is it?? At this point my brain keeps shouting the word "ARRAY!" at me but I just can't see how I can use an array inside the object, or an object inside an array to achieve what I want.
My end goal (in this simplified example) is to be able to then use object-oriented syntax to be able to access certain items and find out specific information about the item such as price, condition etc. For example if I want to know the price of the "coffee maker" I would like to write something like:
stuffToSell["coffee maker"].price
...and then the result above should be 5.
I feel like I'm on the right track but I think I'm missing the array part? Could someone please tell me what I'm missing or maybe what I'm doing completely wrong! And also if it is wrong to have duplicate property names in the same JS object? For example, is it okay to have:
var stuffToSell = {
item : "Coffee Maker",
price : 5,
item : "Mountain Bike",
price : 10,
item : "26 inch TV",
price : 15
};
...it seems wrong because then how does JS know which price goes with which item??
Thanks in advance :)
You're definitely on the right track!
A lot of people will refer to what you're talking about as a hash.
Here's my suggested structure for you:
var store = {
coffee_maker: {
id: 'coffee_maker',
description: "The last coffee maker you'll ever need!",
price: 5,
},
mountain_bike: {
id: 'mountain_bike',
description: 'The fastest mountain bike around!',
price: 10,
},
tv: {
id: 'tv',
description: 'A big 26 inch TV',
price: 15,
},
}
Having a structure like that will let you do this:
store.mountain_bike.price // gives me 10
Need an array instead, say for filtering or looping over?
Object.keys gives you an Array of all the object's keys in the store ['coffee_maker', 'mountain_bike', 'tv']
// Now we just have an array of objects
// [{id: 'coffee_maker', price: 5}, {id: 'mountain_bike', price: 10} ...etc]
var arr = Object.keys(store).map(el => store[el])
Need to just filter for items that are less than 10?
This will give us an array of products less than 10:
// gives us [{id: 'coffee_maker', price: 5}]
var productsUnder10 = arr.filter(el => el.price < 10)
These techniques can be chained:
var productsOver10 = Object.keys(store)
.map(el => store[el])
.filter(el => el.price > 10)
Need to add a product?
store['new_product'] = {
id: 'new_product',
description: 'The Newest Product',
price: 9000,
}
Here's another way, which would be good to start getting used to.
This is a 'safe' way to update the store, read up on immutability in javascript to learn about it
store = Object.assign({}, store, {
'new_product': {
id: 'new_product',
description: 'The Newest Product',
price: 9000,
}
})
...and another way, that you should also read up on and start using:
This is the object spread operator, basically just an easier way to work with immutable structures
store = {
...store,
'new_product': {
id: 'new_product',
description: 'The Newest Product',
price: 9000,
}
}
Resources
JavaScript Arrow Functions
Object and Array Spread Syntax
Immutable Javascript using ES6 and beyond
You can actually use json or create an array of objects.If using a separate file to store the objects, first load the file. Use array filter method to get an new array which matches the filter condition , like you want to get the item with id 1. This will return an array of objects.
var dict = [{
'id': 1,
'name': 'coffee-mug',
'price': 60
},
{
'id': 2,
'name': 'pen',
'price': 2
}
]
function getItemPrice(itemId) {
var getItem = dict.filter(function(item) {
return item.id === itemId
});
return getItem[0].price;
}
console.log(getItemPrice(1))
JSON objects don't support repeated keys, so you need to set unique keys.
Put an id as your key to group your items:
var stuffToSell = {
'1': {
item: "Coffee Maker",
price: 5
},
'2': {
item: "Mountain Bike",
price: 10
}
.
.
.
}
Now you can access the item's price very fast.
Look at this code snippet (Known Ids)
var stuffToSell = {
'1': {
item: "Coffee Maker",
price: 5
},
'2': {
item: "Mountain Bike",
price: 10
},
'3': {
item: "26 inch TV",
price: 15
}
};
let getPrice = (id) => stuffToSell[id].price;
console.log(getPrice('1'));
See? the access to your items it's fast and your code follows a readable structure.
Look at this code snippet (Item's name as key)
var stuffToSell = {
'Coffee Maker': {
price: 5
},
'Mountain Bike': {
price: 10
},
'26 inch TV': {
price: 15
}
};
let getPrice = (id) => stuffToSell[id].price;
console.log(getPrice('Coffee Maker'));
Look at this code snippet (Item's name: price)
var stuffToSell = {
'Coffee Maker': 5,
'Mountain Bike': 10,
'26 inch TV': 15
};
let getPrice = (id) => stuffToSell[id];
console.log(getPrice('Coffee Maker'));
This is a nice evening project, but actually i'm stuck with some headache.
All I need is a function like this example:
result = set("itemCategories[0].items[0].name", "Test")
which should return:
{ itemCategories: [
{
items: [ {name: "Test"} ]
}
}]
...and in case of the given attribute "itemCategories[1].items[2].name" this result:
{ itemCategories: [
null,
{
items: [
null,
null,
{name: "Test"}
]
}
}]
Use lodash#set:
result = lodash.set({}, "itemCategories[0].items[0].name", "Test")
If you are asking about the vanilla JavaScript Set method then you could do this.
/* this is what you are trying to get.
{ itemCategories: [
{
items: [ {name: "Test"} ]
}
}]
*/
var mySet = new Set(); // your set object.
Create your data (number, text, string, object, array, null).
ver data1 = 365;
ver data2 = 'Dragonfly';
ver data3 = {name: 'Bobby', age: 20000, job: 'dj'};
Then you just add to that set using its add method.
mySet.add(data1);
mySet.add(data2);
mySet.add(data3);
So to get what you are looking for you would write this.
var itms = {items: [{name: 'test'}]};
mySet.add(itms);
The good thing about set is that is like an array. So you can use forEach.
mySet.forEach( function(val){
console.log(val); // gets all your data.
});
You can even check if a value is in your data using the has method.
mySet.has(365); // true
mySet.has(36500000); as false
JavaScript Set
I am converting a JSON object array to CSV using Papa Parse JavaScript Library. Is there a way to have the CSV columns arranged in a certain way.
For e.g; I get the column as:
OrderStatus, canOp, OpDesc, ID, OrderNumber, FinishTime, UOM, StartTime
but would like to be arranged as:
ID, OrderNumber, OrderStatus, StartTime, FinishTime, canOp, OpDesc, UOM
The reason why I get the CSV as unarranged is because the JSON data looks like this:
json = [
{
OrderStatus: "Good",
canOp:"True",
OpDesc:"Good to go",
ID:"100",
OrderNumber:"1000101",
FinishTime:"20:50",
UOM:"K",
StartTime:"18:10"
},
...
]
Thanks
Papa Parse allows to specify order of fields in the unparse() function:
var csv = Papa.unparse({
fields: ["ID", "OrderNumber", "OrderStatus", "StartTime", "FinishTime", "canOp", "OpDesc", "UOM"],
data: [{
OrderStatus: "Good",
canOp: "True",
OpDesc: "Good to go",
ID: "100",
OrderNumber: "1000101",
FinishTime: "20:50",
UOM: "K",
StartTime: "18:10"
},
// ...
]
});
console.log(csv);
<script src="https://unpkg.com/papaparse#4.6.3/papaparse.min.js"></script>
<h3>See your dev console for the results</h3>
You don't need any framework to convert from json to csv.
// fields in the order you want them
const fields = ['ID', 'OrderNumber', 'OrderStatus', 'StartTime', 'FinishTime', 'canOp', 'OpDesc', 'UOM'];
const mapper = (key, value) => value === null ? '' : value // how to handle null values
const csv = [
fields.join(','), // header row
...json.map((row) => fields.map((fieldName) => JSON.stringify(row[fieldName], mapper))).join(',')
]
console.log(csv.join('\r\n'))
Outputs:
ID,OrderNumber,OrderStatus,StartTime,FinishTime,canOp,OpDesc,UOM
"100","1000101","Good","18:10","20:50","True","Good to go","K"
"100","1000101","Good","18:10","20:50","True","Good to go","K"