使用 lodash(或 vanilla javascript)对对象数组进行排序和过滤
sort and filter an object array with lodash (or vanilla javascript)
我有这个对象,我想通过按对象仅保留 2 个最高值来排序和过滤。
obj={ A :[{
asset: 9,
biodiversity: 4,
infrastructure: 15,
deflation: 11,
energy: 9
}],
B:[{
asset: 12,
biodiversity: 10,
infrastructure: 9,
deflation: 7,
energy: 15
}],
C:[{
asset: 2,
biodiversity: 12,
infrastructure: 6,
deflation: 6,
energy: 8
}]}
我想按对象的值对对象进行排序,并过滤掉最高的 2 个,例如:
{A :[{
infrastructure: 15,
deflation: 11
}],
B:[{
energy: 15,
asset: 12
}],
C:[{
biodiversity: 12,
energy: 8
}]}
我试过这个排序:
Object.keys(obj).forEach((a) => _.sortBy(obj[a][0])))
但这显然是错误的。
我正在使用 lodash,但也会接受香草 javascript 解决方案。
您可以获取内部对象的条目并按值降序排序,获取前两个 key/value 对并从中构建一个新对象。
const
data = { A: [{ asset: 9, biodiversity: 4, infrastructure: 15, deflation: 11, energy: 9 }], B: [{ asset: 12, biodiversity: 10, infrastructure: 9, deflation: 7, nergy: 15 }], C: [{ asset: 2, biodiversity: 12, infrastructure: 6, deflation: 6, energy: 8 }]},
result = Object.fromEntries(Object
.entries(data)
.map(([k, a]) => [k, a.map(o => Object.fromEntries(Object
.entries(o)
.sort((a, b) => b[1] - a[1])
.slice(0, 2)
))])
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
(Edit/Note:这是基于您最初发布的代码。很高兴看到您更新了问题并去掉了包装数组。)
这是一个相对实用的方法。
secondLargestValue
函数查找每个对象内的阈值。
copyWithoutValsBelowThreshold
函数为我们提供了对象的修改副本。
我们遍历 top-level 对象中的条目并应用这两个函数。
请参阅代码中的注释以进一步说明。
let json = getArray(); // Identifies the original array
// Defines `secondLargestVal` function
const secondLargestVal = someObj =>
// Gets second item of array after sorting numerically in descending order
Object.values(someObj).sort((a, b) => b - a)[1];
// Defines `copyWithoutValsBelowThreshold` function
const copyWithoutValsBelowThreshold = ( (someObj, threshold) => {
// This function doesn't mutate the original value
clone = Object.assign({}, someObj); // Copies obj
for(let prop in clone){
// Loops through properties, deleting non-qualifying ones
if(clone[prop] < threshold){
delete clone[prop];
}
}
return clone;
});
// Defines our main function
const mutateJson = () => {
let entries = Object.entries(json[0]);
entries = entries.map(entry => {
// `entry[0]` is the property name (eg: 'A') -- we don't actually use this
// `entry[1]` is the value (in this case, an array containing a single object)
let obj = entry[1][0]; // Identifies the actual object
const threshold = secondLargestVal(obj); // Identifies minimum value
// Updates the entry, deleting properties whose values are too low
entry[1][0] = copyWithoutValsBelowThreshold(obj, threshold);
return entry;
});
json[0] = Object.fromEntries(entries); // Replaces the top-level object
}
// Calls the main function
mutateJson();
console.log(json);
// Provides the original array
function getArray(){
return [{ A :[{
asset: 9,
biodiversity: 4,
infrastructure: 15,
deflation: 11,
energy: 9
}],
B:[{
asset: 12,
biodiversity: 10,
infrastructure: 9,
deflation: 7,
energy: 15
}],
C:[{
asset: 2,
biodiversity: 12,
infrastructure: 6,
deflation: 6,
energy: 8
}]}]
}
我有这个对象,我想通过按对象仅保留 2 个最高值来排序和过滤。
obj={ A :[{
asset: 9,
biodiversity: 4,
infrastructure: 15,
deflation: 11,
energy: 9
}],
B:[{
asset: 12,
biodiversity: 10,
infrastructure: 9,
deflation: 7,
energy: 15
}],
C:[{
asset: 2,
biodiversity: 12,
infrastructure: 6,
deflation: 6,
energy: 8
}]}
我想按对象的值对对象进行排序,并过滤掉最高的 2 个,例如:
{A :[{
infrastructure: 15,
deflation: 11
}],
B:[{
energy: 15,
asset: 12
}],
C:[{
biodiversity: 12,
energy: 8
}]}
我试过这个排序:
Object.keys(obj).forEach((a) => _.sortBy(obj[a][0])))
但这显然是错误的。 我正在使用 lodash,但也会接受香草 javascript 解决方案。
您可以获取内部对象的条目并按值降序排序,获取前两个 key/value 对并从中构建一个新对象。
const
data = { A: [{ asset: 9, biodiversity: 4, infrastructure: 15, deflation: 11, energy: 9 }], B: [{ asset: 12, biodiversity: 10, infrastructure: 9, deflation: 7, nergy: 15 }], C: [{ asset: 2, biodiversity: 12, infrastructure: 6, deflation: 6, energy: 8 }]},
result = Object.fromEntries(Object
.entries(data)
.map(([k, a]) => [k, a.map(o => Object.fromEntries(Object
.entries(o)
.sort((a, b) => b[1] - a[1])
.slice(0, 2)
))])
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
(Edit/Note:这是基于您最初发布的代码。很高兴看到您更新了问题并去掉了包装数组。)
这是一个相对实用的方法。
secondLargestValue
函数查找每个对象内的阈值。
copyWithoutValsBelowThreshold
函数为我们提供了对象的修改副本。
我们遍历 top-level 对象中的条目并应用这两个函数。 请参阅代码中的注释以进一步说明。
let json = getArray(); // Identifies the original array
// Defines `secondLargestVal` function
const secondLargestVal = someObj =>
// Gets second item of array after sorting numerically in descending order
Object.values(someObj).sort((a, b) => b - a)[1];
// Defines `copyWithoutValsBelowThreshold` function
const copyWithoutValsBelowThreshold = ( (someObj, threshold) => {
// This function doesn't mutate the original value
clone = Object.assign({}, someObj); // Copies obj
for(let prop in clone){
// Loops through properties, deleting non-qualifying ones
if(clone[prop] < threshold){
delete clone[prop];
}
}
return clone;
});
// Defines our main function
const mutateJson = () => {
let entries = Object.entries(json[0]);
entries = entries.map(entry => {
// `entry[0]` is the property name (eg: 'A') -- we don't actually use this
// `entry[1]` is the value (in this case, an array containing a single object)
let obj = entry[1][0]; // Identifies the actual object
const threshold = secondLargestVal(obj); // Identifies minimum value
// Updates the entry, deleting properties whose values are too low
entry[1][0] = copyWithoutValsBelowThreshold(obj, threshold);
return entry;
});
json[0] = Object.fromEntries(entries); // Replaces the top-level object
}
// Calls the main function
mutateJson();
console.log(json);
// Provides the original array
function getArray(){
return [{ A :[{
asset: 9,
biodiversity: 4,
infrastructure: 15,
deflation: 11,
energy: 9
}],
B:[{
asset: 12,
biodiversity: 10,
infrastructure: 9,
deflation: 7,
energy: 15
}],
C:[{
asset: 2,
biodiversity: 12,
infrastructure: 6,
deflation: 6,
energy: 8
}]}]
}