This question already has answers here:
Sort array of objects by string property value
(57 answers)
Closed 5 years ago.
Since there's no official way to sort an object by values, I'm guessing you either (1) Use an array instead or (2) Convert your object to an array using Object.entries(), sort it, then convert back to an object. But option (2) is technically unsafe since Javascript objects aren't supposed to have order.
Now I have a React app where I'm using Redux. I'm storing my data not as an array but as an object iterated by id values. This is what Redux suggests, and I would do it anyways, because of lookup times. I want to sort this redux data, so what I'm currently doing is option (2) of converting to array and then back to object. Which I don't really like.
My question is: Is this what everyone else does? Is it safe to sort an object?
Example:
const sortObject = (obj) => {
//return sorted object
}
var foo = {a: 234, b: 12, c: 130}
sortObject(foo) // {b: 12, c:130, a:234}
this is what I'm currently doing.
My object data structure looks something like this
obj = {
asjsd8jsadf: {
timestamp: 1234432832
},
nsduf8h3u29sjd: {
timestamp: 239084294
}
}
And this is how I'm sorting it
const sortObj = obj => {
const objArray = Object.entries(obj);
objArray.sort((a, b) => {
return a[1].timestamp < b[1].timestamp ? 1 : -1;
});
const objSorted = {};
objArray.forEach(key => {
objSorted[key[0]] = key[1];
});
return objSorted;
};
If you are using the Redux documentation for reference you should also have an array with all of the id's in it. Wouldn't it be easier to just sort that array and then use insertion sort when you add something to the state. Then you could use the sorted array to access the byId property of the state?
Related
This question already has answers here:
How to add prefix to array values?
(5 answers)
Closed 7 months ago.
Let's say there's an object with string values:
const A = { key_a1: "value_a1", key_a2: "value_a2" };
What is the way to clone this object and add some prefix to the values? So I want to convert object A into object B that looks next:
const B = { key_a1: "prefix_value_a1", key_a2: "prefix_value_a2" };
I know about copy syntax like const B = { ...A } but that does not allow to modify values.
You can use Object.entries to turn the keys and values of the original object into an array, and reduce to create a new Object with the same keys of the original object with a prefix.
const A = { key_a1: "value_a1", key_a2: "value_a2" };
const B = Object.entries(A).reduce((acc, [key, value]) => ({
...acc,
[`prefex_${key}`]: value
}), {})
console.log(B)
You can loop over it's values, like:
Object.values(A).map(i => `prefix_${i}`)
This question already has an answer here:
javascript push returning number instead of object [duplicate]
(1 answer)
Closed 8 months ago.
I am experiencing unexpected behaviour of push function.
The problem is with the latest line of code cited below.
export enum non_searchFieldsNames {
language = 'language',
categories = 'categories',
subtitle = 'subtitle',
publishedDate = 'publishedDate',
id = 'id',
}
enum columnsEnum {
title,
authors,
language,
categories,
subtitle,
publishedDate,
}
function toArray(obj: header | contentCategories | sourceFields) {
return Object.entries(obj)
.sort((a, b) => {
return +a - +b;
})
.map(item => item[1]);
}
let sourceFieldsObject: sourceFields = {
[columnsEnum.title]: searchFieldsNames.title,
[columnsEnum.authors]: searchFieldsNames.authors,
[columnsEnum.language]: non_searchFieldsNames.language,
[columnsEnum.categories]: non_searchFieldsNames.categories,
[columnsEnum.subtitle]: non_searchFieldsNames.subtitle,
[columnsEnum.publishedDate]: non_searchFieldsNames.publishedDate,
};
const sourceFieldsArray = toArray(sourceFieldsObject).push(non_searchFieldsNames.id);
The problem is with the latest line of code. The value I do receive here is 7.
When I simplify it like this
const sourceFieldsArray = toArray(sourceFieldsObject)
I receive an array(however, without the value I try to add, of course).
When I split the logic
const sourceFieldsArray = (toArray(sourceFieldsObject));
sourceFieldsArray.push(non_searchFieldsNames.id);
I get what I wanted. Anyway, I would like to have it as one-liner. So, what is my error?
I have tried also
const sourceFieldsArray (toArray(sourceFieldsObject)).push(non_searchFieldsNames.id)
But it does not help.
push modifies the main array directly, and it does not return a new array as you expected, but the count of items in that array.
You can check the below demo for push's returned value
const array = [1,1,1] //3 items
const count = array.push(1) //1 more item
console.log(count) //total is 4 items
If you want to have a one-liner, you can try the cloning approach with the spreading operator
const sourceFieldsArray = [...toArray(sourceFieldsObject), non_searchFieldsNames.id]
Side note that this approach means you're creating a new array completely, so you need to be aware of some performance situations with a huge array.
This question already has answers here:
Get all unique values in a JavaScript array (remove duplicates)
(91 answers)
Closed 1 year ago.
I have this array of objects, my aim is to remove dublicate values from values array, I want the result to be [{name:'test1', values:['35,5', '35,2','35,3']}, {name:'test2', values:['33,2', '34,3', '32,5']}]
I have tried following solution but it does not works, Do you have any suggestions? Thanks in advance
let arr = [{name:'test1', values:['35,5', '35,2', '35,2', '35,3', '35,5']},
{name:'test2', values:['35,1', '35,1', '33,2', '34,3', '32,5']}]
let uniqueArray = arr.values.filter(function(item, pos) {
return arr.values.indexOf(item.values) == pos;
})
console.log(uniqueArray)
}
}
You can easily remove duplicates from an Array by creating a new Set based off it.
Set objects are collections of values. You can iterate through the elements of a set in insertion order. A value in the Set may only occur once; it is unique in the Set's collection
If you want the result in an array, just use spread syntax for that, for example:
let arr = [{
name: 'test1',
values: ['35,5', '35,2', '35,2', '35,3', '35,5']
},
{
name: 'test2',
values: ['35,1', '35,1', '33,2', '34,3', '32,5']
}
];
const uniqueArr = arr.reduce((accum, el) => {
// Copy all the original object properties to a new object
const obj = {
...el
};
// Remove the duplicates from values by creating a Set structure
// and then spread that back into an empty array
obj.values = [...new Set(obj.values)];
accum.push(obj);
return accum;
}, []);
uniqueArr.forEach(el => console.dir(el));
This question already has answers here:
Accessing nested JavaScript objects and arrays by string path
(44 answers)
Closed 3 years ago.
i have objects which have hold x amounts of nested objects:
let obj = {
nestedObject: {
key: value
}
}
or
let obj2 = {
nestedObject2: {
nestedObject3: {
key2: value2
}
}
}
etc.
Getting the values of both those objects is not that difficult:
obj.nestedObject.key
obj['nestedObject']['key]
or
obj2.nestedObject2.nestedObject3.key2
obj2['nestedObject2']['nestedObject3']['key2']
This should happen dynamically though which is what I don't know how to achieve.
I get random objects with the structure above and also a string which tells me where to find the values. For obj2 in the example above I would get the string
"nestedObject2.nestedObject3.key2"
How do I use this information to get the proper value? The two strategies above don't work anymore and something easy like
obj2['nestedObject2.nestedObject3.key2']
doesn't work unfortunately.
You can split the string by the delimiter of a period character, and then reduce to find the appropriate property, going down a level on every iteration.
str.split(".").reduce((a, v) => (a = a[v], a), parent_object);
let o = {
nestedObject2: {
nestedObject3: {
key2: "a key"
}
}
},
str = "nestedObject2.nestedObject3.key2";
let ref = str.split(".").reduce((a, v) => (a = a[v], a), o);
console.log(ref);
This question already has answers here:
From an array of objects, extract value of a property as array
(24 answers)
Construct an array of elements from an array of objects? [duplicate]
(2 answers)
Closed 8 years ago.
Lets say I have an array of objects:
var employees=[]
employees[0]={name:"George", age:32, retiredate:"March 12, 2014"}
employees[1]={name:"Edward", age:17, retiredate:"June 2, 2023"}
employees[2]={name:"Christine", age:58, retiredate:"December 20, 2036"}
employees[3]={name:"Sarah", age:62, retiredate:"April 30, 2020"}
Is there an array function that will allow me to get one property as an array,
for example:
namesArray = employees.reduceToProperty('name'); // none existent function i made up!
// should return ["George","Edward","Christine","Sarah"]
I know how get the desired result with a loop, I am just hoping for an array function or combination of functions exist that can do this in one line.
var names = employees.map(function(i) {
return i.name;
});
names is now an array containing the name-properties of the objects.
Array.prototype.map maps one array to another:
var names = employees.map(function (val) {
return val.name;
});
// ['George', 'Edward', 'Christine', 'Sarah']
If you find yourself doing this frequently, you might consider using pluck from Underscore/Lo-Dash:
var listOfPropertyNames = _.pluck(list, 'propertyName');
underscorejs.org/#pluck
lodash.com/docs#pluck
If you don't want to do include a library, it is of course possible to write your own pluck for use on your code base:
function pluck(list, propertyName) {
return list.map(function(i) {
return i[propertyName];
});
}
And running it:
pluck([{name: 'a'}, {name: 'b'}], 'name');
["a", "b"]
You'll have to decide how to handle the edge cases like:
object in the list not having the property
an undefined being in the list
?