How to order localStorage by KEY ASC? - javascript

I save data to localStorage.
To be able to order the localStorage i use milliseconds as key.
(But localStorage doesn't sort or order, so i need to build a array or object that i can sort by key)
var key = Date.now();
var value = {
"id": id,
"name": name
};
//ADD DATA TO OBJECT
localStorage.setItem(key, JSON.stringify(value));
Now i'd like to fetch localStorage and display the data ordered by key asc.
I tried:
//CONSOLE LOG LOCALSTORAGE
Storage {1614866637849: "{"id":"1","name":"A"}", 1614866687890: "{"id":"3","name":"C"}", 1614866642078: "{"id":"2","name":"B"}", length: 3}
//DECLARE NEW OBJ
var items = {};
//LOOP THREW localStorage
Object.keys(localStorage).forEach(function(key){
//FETCH THIS ROUND DATA
items[key] = JSON.parse(localStorage.getItem(key));
});
//CONSOLE LOG ITEMS
1614866637849: {…}, 1614866687890: {…}, 1614866642078: {…}}
//SORT ITEMS
var sorted_items = Object.keys(items).reduce((accumulator, currentValue) => {accumulator[currentValue] = items[currentValue]; return accumulator;}, {});
//CONSOLE LOG SORTED ITEMS
1614866637849: {…}, 1614866687890: {…}, 1614866642078: {…}}
So it looks like my ordering function does nothing?
How can i loop out my data from localStorage by key ASC?
The order i wan't is:
....49
....78
....90

If you want to just print the results in key order, just sort the keys before calling forEach.
Object.keys(localStorage).sort().forEach...
If you want sorted "pairs", because key order is not guaranteed, you can try the following.
const storage = {
1614866637849: '{"id":"1","name":"A"}',
1614866687890: '{"id":"3","name":"C"}',
1614866642078: '{"id":"2","name":"B"}'
};
const pairs = Object.entries(storage)
.map(([key, value]) => ({
key: parseInt(key),
value: JSON.parse(value)
}))
.sort(({ key: keyA }, { key: keyB }) => keyA - keyB);
console.log(pairs);
.as-console-wrapper { top: 0; max-height: 100% !important; }

You can do it this way:
Object.entries(YOUROBJECT).sort().reduce( (o,[k,v]) => (o[k]=v,o), {} );
Your example:
var yourdata = {1614866637849:{"id":"1","name":"A"}, 1614866687890:{"id":"3","name":"C"}, 1614866642078:{"id":"2","name":"B"}, length: 3};
console.log("BEFORE", yourdata);
console.log("NOW", Object.entries(yourdata).sort().reduce( (o,[k,v]) => (o[k]=v,o), {} ));
Result:
1614866637849: {id: "1", name: "A"}
1614866642078: {id: "2", name: "B"}
1614866687890: {id: "3", name: "C"}
Credit goes to:
Sort JavaScript object by key
#sravan ganji

The easiest and smartest way was commented by #Mr.polywhirl
Just add .sort() in the forEach:
Object.keys(localStorage).sort().forEach(function(key){..

Related

2D Array Object to 1D array filter function

Use Case 1
Assuming i have 2dArray Object of
let arr = [{'getName':'Report1'},{'getName':'User'},{'getName':'report 2'},{'getName':'User'},{'getName':'User'}]
let _NotRequiredSheet = ['User','Report 254',...]
Im trying to optimise my script with functional programming which will return me an array of
['report1','report2']
The current Method im using which does not have any error is :
for(let i =0;i < arr.length;i++){
if(arr[i].getName != _NotRequiredSheet[0]){
console.log(arr[i].getName)
}
}
But this will impact if _notrequiredSheet have a big list of what is not required
I tried using this approach which is using filter but since its 2dObject Array, im unsure how should this be implemented.
What i did on my poc is
//Approach 1 : Not Working
let result = arr.filter(function (arr) {
return arr.getName != _NotRequiredSheet.values();
})
//Output should be as 1dArray['report1','report2'] , not (5) [{…}, {…}, {…}, {…}, {…}]
console.log(result)
//Approach 2 : Will output as 2D array with filtered value
// Will require to hardcord the index which is not advisable
let result = arr.filter(function (arr) {
return arr.getName != _NotRequiredSheet[0];
})
console.log(result)
i wanted to check if there is any way i could pass on using for loop with filter function. Result should return as 1D array which is
['Report1','Report2']
Use case 1 is Solved
Use Case 2 : 2D Object Array
Assuming data is declared as
let arr2 = [
{$0:{'Name':'Report1'}},
{$0:{'Name':'Report2'}},
{$0:{'Name':'User'}}
]
Result should show this on console.log (2) [{…}, {…}] , filter function will remove 'User' as its reflected in _NotRequiredSheet.
Using the syntax i wrote
let result = arr2.map(item => item.$0.Name).filter(Name => !_NotRequiredSheet.includes(Name))
This will return as a single array
You could filter your data with looking for unwanted values and map only the wanted property.
const
data = [{ getName: 'Report1' }, { getName: 'User' }, { getName: 'report 2' }, { getName: 'User' }, { getName: 'User' }],
_NotRequiredSheet = ['User', 'Report 254'],
result = data
.filter(({ getName }) => !_NotRequiredSheet.includes(getName))
.map(({ getName }) => getName);
console.log(result);
With a Set
const
data = [{ getName: 'Report1' }, { getName: 'User' }, { getName: 'report 2' }, { getName: 'User' }, { getName: 'User' }],
_NotRequiredSheet = ['User', 'Report 254'],
take = k => o => o[k],
hasNot = s => v => !s.has(v),
comp = f => g => o => f(g(o)),
result = data
.filter(
comp(hasNot(new Set(_NotRequiredSheet)))(take('getName'))
)
.map(({ getName }) => getName);
console.log(result);
I'd recommend using reduce()
so you can return something based on _NotRequiredSheet.includes(cur.getName)
let arr = [{'getName':'Report1'},{'getName':'User'},{'getName':'report 2'},{'getName':'User'},{'getName':'User'}]
let _NotRequiredSheet = ['User','Report 254' ];
let res = arr.reduce((prev, cur) => {
if (_NotRequiredSheet.includes(cur.getName)) {
return prev;
} else {
return [ ...prev, cur.getName ];
}
}, []);
console.log(res);

How to rename object property in javascript?

I have got a nested object. I want to rename the object properties.
{
0: {value: "can_view"},
1: {value: "can_create"}
}
My output would be:
{
user_can: "can_view",
user_view: "can_create"
}
You can do that in three steps:
Get the entries using Object.entries()
Use map() on it and replace each key with the desired value
Convert it back to object using Object.fromEntries()
const obj = {
0: {value: "can_view"},
1: {value: "can_create"}
}
const res = Object.fromEntries(Object.entries(obj).map(([k, v]) => [v.value, v.value]));
console.log(res)
Improving Maheer Ali's answer.
Here you go:
const obj = {
0: {value: "can_view"},
1: {value: "can_create"}
}
var res = Object.fromEntries(Object.entries(obj).map(([k, v]) => [v.value.replace("can", "user"), v.value]));
var myResutls = JSON.stringify(res).replace(/"(\w+)"\s*:/g, '$1:');
console.log(myResutls);
alert(myResutls)
OUTPUT:
{
user_view: "can_view",
user_create: "can_create"
}

Map an object array with unknown length and unknown key names

Here are some object arrays:
1. [{id:'1', code:'somecode', desc:'this is the description'}, {...}, {...}]
2. [{fname:'name', lname:'last name', address:'my address', email:'my#email.com'}, {...}, {...}]
What I need to do is create a function where I pass an array and map their object keys to generic keys so they become like this:
1. [{key1:'1', key2:'somecode', key3:'this is the description'}, {...}, {...}]
2. [{key1:'name', key2:'last name', key3:'my address', key4:'my#email.com'}, {...}, {...}]
When I do this
let keys: string[] = Object.keys(this.options[0])
this.replacedItems = this.options.map(item => {
return{
key1: item[keys[0]],
key2: item[keys[1]],
key3: item[keys[2]],
}
});
it works fine, but since the object's properties number is not fixed, I tried this
let keys: string[] = Object.keys(this.options[0])
this.replacedItems = this.options.map(item => {
let i=0;
keys.forEach(key=>{
let newKey = 'key'+i;
i++
return { newKey: item[key] }
});
});
which rerurns an array of undefined...
What am I doing wrong?
Take the second parameter of .map to get the current index you're iterating over, and concatenate it with 'key'. You can also use Object.values instead of Object.keys to get the values immediately (since you're not actually using the original keys):
const options = [{id:'1', code:'somecode', desc:'this is the description'}];
const replacedItems = options.map(obj => Object.fromEntries(
Object.values(obj).map((val, i) => ['key' + (i + 1), val])
));
console.log(replacedItems);

Why i can't give "1" as keyname in local Storage?

I want to give key name as "1" but its not working.
I want to pass a string like this in local storage with key "1" eg
1:["name":"kalidas"]
var array = [];
t = "kalidas";
t1 = "array";
if (localStorage.getItem("1") === null) {
a = [
{
name: t,
},
];
localStorage.setItem("1", JSON.stringify(a));
array = JSON.parse(localStorage.getItem("1"));
} else {
array = JSON.parse(localStorage.getItem("1"));
a = {
name: t,
};
array.push(a);
localStorage.setItem("1", JSON.stringify(array));
}
The output I'm always getting is Storage 
{1: "1", length: 1}
However, if I change key name it works perfectly.
localStorage.setItem('1', 'Some String here') works as expected.
Yes, the response of your code would be
[{…}]
0: {name: "kalidas"}
length: 1
If you look at your storage like console.log(localStorage) you will get
Storage {1: "1", length: 1}
1: "1"
length: 1
that's true
However, if you try to fetch stored data by key i.e. localStorage.getItem('1') you will get your valid response
"[{"name":"kalidas"}]"
You could write a simple wrapper that always roundtrips things to JSON:
function saveValue(key, value) {
localStorage.setItem(key, JSON.stringify(value));
}
function loadValue(key, defaultValue=null) {
const value = localStorage.getItem(key);
if(value === null) return defaultValue;
return JSON.parse(value);
}
const a = {name: 'kalidas'};
saveLocalStorage('1', a);
const b = loadLocalStorage('1');

Convert single object into array of objects

I have an object that looks like:
var data = {first: '12/1/2019', second: '12/15/2019'}
I am trying to get into an array of objects using its keys and values like so:
var array = [
{phase: 'first', date: '12/1/2019'},
{phase: 'second', date: '12/15/2019'}
]
I have tried various things, but the closest I have gotten is using something like:
var array = Object.entries(data).map(([key, value]) => ({key,value}));
This gives me an array of objects like:
[
{key: 'first', value: '12/1/2019'},
{key: 'second', value: '12/15/2019'}
]
I'm close! but i can't figure out how to change key and value to be phase and date. Can someone please help me out?
You can actually just rename your key and value parameter names:
var array = Object.entries(data).map(([phrase, date]) => ({phrase,date}));
Try adding labels in object.
var data = {
first: '12/1/2019',
second: '12/15/2019'
}
var array = Object.entries(data).map(([key, value]) => ({
phase: key,
date: value
}))
console.log(array)
You are almost there try by adding the key to return object
var data = {
first: '12/1/2019',
second: '12/15/2019'
}
var array = Object.entries(data).map(([key, value]) => ({
phase: key,
date: value
}));
console.log(array)
Try the following solution using for...in to iterates over all non-Symbol, enumerable properties of an object.
const data = { first: '12/1/2019', second: '12/15/2019' };
const dataset = [];
for (const key in data) {
if (data.hasOwnProperty(key)) {
const element = data[key];
dataset.push({
phase: key,
date: element
});
}
}
console.log(dataset);
You can use map() on Object.keys()
var data = {first: '12/1/2019', second: '12/15/2019'}
let arr = Object.keys(data).map(x => ({phase:x,date:data[x]}))
console.log(arr)
You can also use Object.entries() and map() but give different names to the parameters destructed
var data = {first: '12/1/2019', second: '12/15/2019'}
let arr = Object.entries(data).map(([phase,date]) =>({phase,date}))
console.log(arr)
First extract the key (phase) and value (date) from the data object by Object.entries then use Array.reduce to accumulate and form the new object into an array.
const data = {first: '12/1/2019', second: '12/15/2019'}
const arr = Object.entries(data).reduce((acc, [phase, date]) => acc.concat({phase, date}), []);
console.log(arr);

Categories