在javascript中,如何在数组中保留具有特定唯一属性的对象?

在javascript中,如何在数组中保留具有特定唯一属性的对象?,javascript,underscore.js,Javascript,Underscore.js,我有这样一个数组: var myarray = [ {"scaleId":"001","currentWeight":0.200} {"scaleId":"002","currentWeight":0.300}, {"scaleId":"001","currentWeight":0.255}, {"scaleId":"002","currentWeight":0.000}, {"scaleId":"003","currentWeight":0.340},

我有这样一个数组:

var myarray = [
    {"scaleId":"001","currentWeight":0.200}
    {"scaleId":"002","currentWeight":0.300},
    {"scaleId":"001","currentWeight":0.255},
    {"scaleId":"002","currentWeight":0.000},
    {"scaleId":"003","currentWeight":0.340},
    ]
我想保留具有唯一scaleId的对象。因此,对于上面的示例,输出如下所示(如果scaleId重复,则可以保留任何随机对象):


我已经在我的应用程序中使用了下划线库,所以我对使用下划线的实现很满意。我已经想出了一个解决方案,但它并没有像预期的那样起作用。所以,任何帮助都将是巨大的

使用
reduce
和内部回调检查累加器对象中是否有具有相同scaleId的键。如果是,则将该值添加到该键。最后使用
Object.values
创建一个值数组

var myarray=[{
“scaleId”:“001”,
“当前重量”:0.200
},
{
“scaleId”:“002”,
“当前重量”:0.300
},
{
“scaleId”:“001”,
“当前权重”:0.255
},
{
“scaleId”:“002”,
“当前重量”:0.000
},
{
“scaleId”:“003”,
“当前重量”:0.340
}
]
让数据=myarray.reduce((acc,curr)=>{
如果(!acc[当前刻度]){
acc[当前刻度]=当前刻度
}
返回acc;
}, {});

console.log(Object.values(data))
Map
s和
Set
s通常是保持唯一性的适当结构。下面是一个简单的函数,它使用
映射
来维护给定属性名称的单个唯一值:

const uniqByProp=(prop)=>(xs)=>
[…新映射(xs.Map((x)=>[x[prop],x])).values()]
var myarray=[{scaleId:“001”,currentWeight:0.200},{scaleId:“002”,currentWeight:0.300},{scaleId:“001”,currentWeight:0.255},{scaleId:“002”,currentWeight:0.000},{scaleId:“003”,currentWeight:0.340}]
控制台日志(
uniqByProp('scaleId')(myarray)
)
.as控制台包装{min height:100%!important;top:0}
您可以这样做(如果您使用的是ES6/ES2015或更高版本) 首先使用Set筛选唯一的scaleID,并使用array.find方法提供一个新数组

var myarray = [
    {"scaleId":"001","currentWeight":0.200},
    {"scaleId":"002","currentWeight":0.300},
    {"scaleId":"001","currentWeight":0.255},
    {"scaleId":"002","currentWeight":0.000},
    {"scaleId":"003","currentWeight":0.340},
]

let scaleIds = [...new Set(myarray.map(item => item.scaleId))];
let filtered = []
scaleIds.forEach(scaleId => filtered.push(myarray.find(item => item.scaleId === scaleId)))

console.log(filtered)
您还可以使用简化聚合逻辑:

让myarray=[
{scaleId:'001',当前权重:0.2},
{scaleId:'002',当前权重:0.3},
{scaleId:'001',当前权重:0.255},
{scaleId:'002',当前权重:0},
{scaleId:'003',当前权重:0.34}
];
myarray=Object.values(
myarray.reduceRight(
(acc,cur)=>(acc[cur.scaleId]=cur,acc),
{}
)
).reverse();//如果输出顺序对您很重要,则为可选

log(myarray)出于兴趣,我是否可以阅读有关您使用的特定代码样式的资源?虽然我知道这在那些喜欢FP的人中很常见,但我并不认为这经常被使用。@PatrickRoberts:我不确定你对我的风格感兴趣的是什么。我是一个FP迷,所以我想我符合一些刻板印象!我更喜欢。我更喜欢简单的单一用途但理想的通用函数,但这在我看来只是常识。我愿意写相当宽的行,但我喜欢一些不寻常的空白(例如
xs.map(…)
而不是
xs.map(…)
,但这是一个比一致的样式更重要的小特性。或者是别的什么?我特别注意的是空格的使用。当时没有这方面的标准?我见过面向FP的人在编写JavaScript时非常一致地使用它。@PatrickRoberts。我不知道有任何样式指南建议这样做。我借用了它,还有一些世卫组织提出的其他格式化想法后来改变了空白格式。该用户的帖子包含了大量有用的技术。这些格式显然源自类似LISP的语言格式。
var myarray = [
    {"scaleId":"001","currentWeight":0.200},
    {"scaleId":"002","currentWeight":0.300},
    {"scaleId":"001","currentWeight":0.255},
    {"scaleId":"002","currentWeight":0.000},
    {"scaleId":"003","currentWeight":0.340},
]

let scaleIds = [...new Set(myarray.map(item => item.scaleId))];
let filtered = []
scaleIds.forEach(scaleId => filtered.push(myarray.find(item => item.scaleId === scaleId)))

console.log(filtered)