Javascript:使用reduce/map等创建具有特定值的对象数组

Javascript:使用reduce/map等创建具有特定值的对象数组,javascript,arrays,Javascript,Arrays,我想从对象数组创建对象数组,以下是数据: // Input: const shippingMethodOptions = [{ id: 1, carrier_token: 'fedex', carrier_name: 'Fedex', weight: 1, price: 3 }, { id: 2, carrier_token: 'fedex', carrier_name: 'Fedex', weight: 2, price: 6 }, { id: 3,

我想从对象数组创建对象数组,以下是数据:

// Input:
const shippingMethodOptions = [{
  id: 1,
  carrier_token: 'fedex',
  carrier_name: 'Fedex',
  weight: 1,
  price: 3
}, {
  id: 2,
  carrier_token: 'fedex',
  carrier_name: 'Fedex',
  weight: 2,
  price: 6
}, {
  id: 3,
  carrier_token: 'fedex',
  carrier_name: 'Fedex',
  weight: 6,
  price: 9
}, {
  id: 4,
  carrier_token: 'usps',
  carrier_name: 'Usps',
  weight: 6,
  price: 9
}, {
  id: 5,
  carrier_token: 'delaware',
  carrier_name: 'Delaware',
  weight: 5,
  price: 10
}]
如您所见,数据包含
carrier\u token
carrier\u name
,我想创建一个具有唯一
carriers
的输出数组,如下所示:

// Output:
const carriers = [{
  carrier_token: 'fedex',
  carrier_name: 'Fedex'
}, {
  carrier_token: 'usps',
  carrier_name: 'USPS'
}, {
  carrier_token: 'delaware',
  carrier_name: 'Delaware'
}]
我所尝试的是用for循环构建它,但是我很想知道这是否可能以更干净的方式实现(reduce?)

到目前为止,这是我目前的解决方案(不过,我还是想知道是否有可能使用Reduce等工具使其更干净)


看起来是一个很直接的工作

你需要的是一种跟踪现有运营商的方法。我建议使用标记并存储由标记和名称生成的密钥,例如,在字符串中,如
:“

const shippingMethodOptions=[{“id”:1,“承运人代币”:“联邦快递”,“承运人名称”:“联邦快递”,“重量”:1,“价格”:3},{“id”:2,“承运人代币”:“联邦快递”,“承运人名称”:“联邦快递”,“重量”:2,“价格”:6},{“id”:3,“承运人代币”:“联邦快递”,“承运人名称”:“联邦快递”,“重量”:6,“价格”:9},{“id”:4,“承运人代币”:“usps”,“承运人名称”:“usps”,“重量”:6,“价格”:9},{:5,“承运人代币”:“特拉华”,“承运人名称”:“特拉华”,“重量”:5,“价格”:10}]
const carriers=shippingMethodOptions.reduce(函数(arr、smo){
let key=`${smo.carrier\u token}:${smo.carrier\u name}`
返回此.has(键)?arr:this.add(键)和&arr.concat({
载波令牌:smo.carrier\u令牌,
承运人名称:smo.carrier\u名称
});
}.bind(新集合(),[]))

控制台。信息(运载工具)< /代码> 我会考虑使用<代码>还原()/<代码> <代码> map()>代码>,其中映射条目具有基于<代码> ${CaveRyToMe}:${CaveRyNeX}//Cord>和所需对象格式中的值。然后在映射的
.values()
上使用
Array.from()

const shippingMethodOptions=[{“id”:1,“承运人代币”:“联邦快递”,“承运人名称”:“联邦快递”,“重量”:1,“价格”:3},{“id”:2,“承运人代币”:“联邦快递”,“承运人名称”:“联邦快递”,“重量”:2,“价格”:6},{“id”:3,“承运人代币”:“联邦快递”,“承运人名称”:“联邦快递”,“重量”:6,“价格”:9},{“id”:4,“承运人代币”:“usps”,“承运人名称”:“usps”,“重量”:6,“价格”:9},{:5,“承运人代币”:“特拉华”,“承运人名称”:“特拉华”,“重量”:5,“价格”:10}]
const carriers=Array.from(
shippingMethodOptions.reduce((映射,{carrier\u token,carrier\u name})=>{
const key=`${carrier\u token}:${carrier\u name}`
如果(!map.has(key))map.set(key,{carrier\u token,carrier\u name})
返回图
},新映射())。值()
)

console.log(carriers)
@AndrewLi很抱歉,我用for循环进行了尝试,但我想知道是否可以使用reduce/map等。能否将您的尝试包括在帖子中?@AndrewLi是的,done@AndrewLi我认为如果一个答案正确地回答了问题,就投否决票是不公平的。根据你对我答案的评论,即使我的答案是正确的,你也会投反对票。我也会非常透彻地解释我的代码,但我会从简单问题的代码转储开始,然后编辑答案,这样我就有机会在其他人的代码转储、投票和/或接受之前被看到。@Clonkex我认为这样鼓励不良行为是不公平的。由于OP当时没有表现出他们的努力,它可能会向其他海报发送信息,要求有人为他们编写代码是可以的。如果你的回答是正确的,并且有现成的解释,我会投赞成票。我有一个非常相似的答案+1达姆。我认为我是一个好的JS程序员,直到我看到这一点,并意识到我不知道发生了什么。这种编码在我看来很难理解。@Clonkex nope~@AndrewLi我确实知道
reduce
是如何工作的,因为我写了自己的代码来解决它(),但我不明白短路在这里是如何应用的,我想
bind
是特定于jQuery的。。。看来我有一些痛苦的学习要完成:/@Clonkex供参考~小心,你会匹配
“fede”+“xFedex”
,等等,你可以缩短回调到
返回映射。有(键)吗?map:map.set(key,obj)
as
set
返回map@Phil-另一个很好的观点,谢谢。我发现
if
更容易阅读,因为这样我就不必记住
.set()
返回的内容。但另一方面,使用您的建议意味着可以从arrow函数中删除花括号和
return
关键字,至少从我的第二个版本中是这样,该版本没有
key
变量。您实际上不需要
reduce
,只需执行
新建映射(data.Map(x=>[x.token,{x.token x.name})]
const getCarriers = options => {
  const carriers = []

  options.forEach(({ carrier_token, carrier_name }) => {
    const foundIndex = _.findIndex(carriers, carrier => carrier.carrier_token === carrier_token)

    if (foundIndex !== -1) {
      return
    }

    carriers.push({
      carrier_token,
      carrier_name
    })
  })

  return carriers
}

const carriers = getCarriers(shippingMethodOptions)