I have array of object tree
var tree = [{
"id": "1",
"name": "one",
"child": [],
}, {
"id": "2",
"name": "two",
"child": [{
"id": "21",
"name": "twentyOne",
"child": [],
},{
"id": "22",
"name": "twentyTwo",
"child": [],
}],
}, {{
"id": "3",
"name": "three",
"child": [],
},
}].
Which one is the best way to store array of objects in localStorage?
Is it better to use another format?
There are several methods:
getItem
getAllItem
removeItem
saveItem
But there are child arrays of objects. It means that I will use recursive search to find necessary object.
Save the data in LocalStorage as an array, or array of simple objects, but try to keep it DRY (don't repeat yourself). For example, if you have a list of people, keep an array of the people, but don't keep a separate variable for the count.
What you want is basically a "state". As long as you keep it minimal you will be fine. Then you can use lodash or underscore to find, merge, add, remove elements from that array.
Related
I'm a JS beginner and I'm stuck with array/objects items.
I get a JSON file with a fetch request and I would like to extract a part of the data.
My data looks like this:
{
"profil": [
{
"name": "",
"id": ,
"city": "",
"country": "",
"tags": ["", "", "", ""],
"text": "",
"price":
},
So it's an object, which contain an array which contain a bunch of objects which contain a "tags" array....
I don't find a way to access tags items (without array index) with forEach loops...
My final purpose with this is to collect a single list of tags that exists in my object list.
How can I do this?
Using Array#flatMap:
const data = {
"profil": [
{ "tags": ["1", "2", "3", "4"] },
{ "tags": ["5", "6", "7", "8"] }
]
};
const tags = data.profil.flatMap(({ tags = [] }) => tags);
console.log(tags);
Edit: if you need the tags to be unique, you can use Set:
console.log([...new Set(tags)]);
I have a json array of objects and want to find a way to get the property names into another array.
[
{
"ID": 12345,
"SID": 1111,
"DataPoint1": [
{
"Name": "SD",
"Activity": "KT",
"Group":"Test"
}
}
]
I want to be able to extract all the property names of DataPoint1 into its own array:
New-->
[Name, Activity, Group]
I was looking into loadash but couldn't find anything. Any ideas? Thanks.
You could use _.keys(data[0].DataPoint1[0]) to get the keys as an array.
const data = [{
"ID": 12345,
"SID": 1111,
"DataPoint1": [{
"Name": "SD",
"Activity": "KT",
"Group": "Test"
}]
}]
console.log(_.keys(data[0].DataPoint1[0]))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
Answered my own question :)
This did the trick:
Object.getOwnPropertyNames(array[0].DataPoint1[0])
Am getting Data from server in below JSON format
{
"Data": [
{
"Id": "1",
"Number": 0,
"Modify": {
"Id": 0,
"Name": "a"
}
},
{
"Id": "2",
"Number": 1,
"Modify": {
"Id": 1,
"Name": "b"
}
}
]}
And am trying to create a new copy(Rename) of Modify inside the same object because my other data is expecting JSON with same format but different name for modify.
So i though i would foreach and create copy of the same which will form like below
{
"Data": [
{
"Id": "1",
"Number": 0,
"Modify": {
"Id": 0,
"Name": "a"
},"New": {
"Id": 0,
"Name": "a"
}
},
{
"Id": "2",
"Number": 1,
"Modify": {
"Id": 1,
"Name": "b"
},
"New": {
"Id": 1,
"Name": "b"
}
}
]}
Is there a better approach i can rename the object or should i create a copy. What is the better way to copy ?
Thanks
For loop is a fine way to do that.. data[i].Name = data[i].Modify;. Im fairly sure there isn't a "better" way than this in Javascript.
There's no other way than the one suggested by #MjrKusanagi, nevertheless I suggest another approach.
Make a function that takes your original object and replaces the selected key with the new name, returning a new object without changing the original one (immutability)
The function could take 3 arguments:
function modifyObject(object, oldKey, newKey) {...}
Inside the function you could use the Object.assign method to create a copy of the original object (a copy, not a reference):
var newObj = Object.assign({}, object);
After that, you can change the key name by creating a new one and don't forget to remove old key from the new object:
newObj.newKey = newObj.oldKey;
delete newObj.oldKey,
Finally you can return this new object and even use this function every time you need to do anything similar.
Using the delete is considered bad practice, but at least here you are not mutating your original source, so you can depend in its content over all your application's life cycle.
I've got a question about best practice when designing JSON file which will be displayed by Backbone.js. I know that Backbone is completly agnostic in this topic, but maybe someone will give me good advice in this certain situation.
In the end, I need to have some views which will look like this
On 4th of July, in _____ we calebrate ____ day.
___ means a gap in text, where I'll have an text input or select (depends on type) which correctness will be verified.
So, I need to have a JSON file that describes that piece of text.
I thought about something like this
"body": [
{
"preInputText": "On 4th of July, in ",
"postInputText": "",
"answersID": ["1", "2"]
},
{
"preInputText": "we calebrate ",
"postInputText": " day",
"answersID": ["3"]
}
]
"answers": [
{
"ID": "1",
"content": "USA",
"correct": true
},
{
"ID": "2",
"content": "Canada",
"correct": false
},
{
"ID": "3",
"content": "Independent",
"correct": true
}
]
or, maybe simpleier, but not-so-flat
"body": [
{
"preInputText": "On 4th of July, in ",
"postInputText": "",
"answers": [
{
"ID": "1",
"content": "USA",
"correct": true
},
{
"ID": "2",
"content": "Canada",
"correct": false
},
]
}
]
etc…
So, first approach enforce creating two collections, passing them into one view, and checking values beetween them.
The second, just one collection of models that contains both body and answers, but parsing them at initialization and using nested construction.
I don't know is it a bad pratice (to use nested models), but as i read backbone was designed to think in the more flat way.
Maybe there is some kind of another logic? What do you think?
Thanks!
I'm more with the first approach (the flat one) and I don't agree with you that it enforce creating two collections.
You can always create a single collection and override it's parse function, something like this :
var MyCollection = Backbone.Collection.extend({
...
parse: function(resp) {
this.answers = new Backbone.Collection(resp.answers);
return resp.body;
}
});
...
// myCollection is an instance of MyCollection
myCollection.models // refer to questions
myCollection.answers // refer to answers
"body": [
{
"preInputText": "On 4th of July, in ",
"postInputText": "",
"answers" [ { "ID": "1", "content": "USA", "correct": "true"},
{ "ID": "1", "content": "canada", "correct": "false"}
]
},
{
"preInputText": "we calebrate ",
"postInputText": " day",
"answersID": [{ "ID": "3", "content": "Independent", "correct": "true"},
]
}
]
Using this structure, you need to use one collection. Then you can treat each object in this as a model and you can render these using their separate views in a collection view. So need to use nested models here
I know there's plenty of answers on this and most are suggesting looping thru the object, returning what you need, I'm not sure this is the best approach, in my case anyway.
What I have is array with entries referencing to another array people(with id and name) by person_id and projects(with id and name) by project_id.
What I need is to be able to access project and person with a particular id inside the loop on entries, so I can get their names. Doing what others have suggested I'd loop thru people and projects inside each irritation of entries, which seems like awful lot of looping.
So I thought I'd make something I called a "hashtable" from both people and projects on init, which means pretty much creating a new objects people_hashtable and projects_hashtable where key would be the id
so
[
{
"id": "8",
"name": "John Doe"
}
]
would became
{
"8": {
"name": "John Doe"
}
}
this way I'd have easy access to the name without looping all the time while still maintaining the old array with its original order(that's why I'm not outputting it this way directly from server, you can't quite order an object and I'm using both people and projects in a selectbox, which needs to be ordered by name).
Am I doing it right? Are there better way? Or should I forget this completely and stick with the search loop as suggested in other question?
I'm trying to be as efficient as possible on both server and client side.
You basically doubled all the objects just to avoid loop. So, unless you have some bad performance issues, I would avoid that.
In case you really, really need a kind of hashmap, I would prefer storing the array's index instead of another copy of the object:
// array
var arr = [
{
"id": "8",
"name": "John Doe"
}
];
// lookup table
var lookup = {
"8": 0
}
Of course doing that, means you can't modifying the array's without rebuild the hashmap.
Generate it's quite simple:
var lookup = arr.reduce(function(lookup, item, index) {
lookup[item.id] = index;
return lookup;
}, {});
You can also use that to generate the object you mentioned your question:
var lookup = arr.reduce(function(lookup, item) {
lookup[item.id] = {name: item.name};
return lookup;
}, {});
But as I said it's something I would avoid.
Following code may help you. JSFIDDLE
var arr = [
{
"id": "8",
"name": "John Doe"
}
];
var obj = {};
for(var i=0; i< arr.length; i++){
obj[arr[i].id] = {name: arr[i].name};
}
console.log(obj);
var articles= {
"item1":{
"id":"155",
"name":"First Item",
"value":-5199.6
},
"item2":{
"id":"255",
"name":"Second Item",
"value":-424.91
}
}
var ids = [];
for(var item in articles) {
ids.push(articles[item]['id']);
}
console.log(ids);
This lib https://github.com/paularmstrong/normalizr makes it pretty easy to do. Both normalization and denormalization.
It can turn this
{
"id": "123",
"author": {
"id": "1",
"name": "Paul"
},
"title": "My awesome blog post",
"comments": [
{
"id": "324",
"commenter": {
"id": "2",
"name": "Nicole"
}
}
]
}
into this
{
result: "123",
entities: {
"articles": {
"123": {
id: "123",
author: "1",
title: "My awesome blog post",
comments: [ "324" ]
}
},
"users": {
"1": { "id": "1", "name": "Paul" },
"2": { "id": "2", "name": "Nicole" }
},
"comments": {
"324": { id: "324", "commenter": "2" }
}
}
}
and the other way around.