繁体   English   中英

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

[英]Javascript: Create array out array of objects with certain value using reduce / map etc

我想从一个对象数组创建一个对象数组,这是数据:

// 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_tokencarrier_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等使其更清洁)

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)

看起来像一个非常简单的减少工作。

您需要的是一种跟踪现有运营商的方法。 我建议使用Set和存储由令牌和名称创建的密钥,例如在"<token>:<name>"类的字符串中。

 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}] const carriers = shippingMethodOptions.reduce(function(arr, smo) { let key = `${smo.carrier_token}:${smo.carrier_name}` return this.has(key) ? arr : this.add(key) && arr.concat({ carrier_token: smo.carrier_token, carrier_name: smo.carrier_name }); }.bind(new Set()), []) console.info(carriers) 

我将Set绑定到reduce回调,因此可以通过this关键字使用它,但是您可以在回调范围之外轻松创建它并将其存储在变量中,例如

const keys = new Set()

我考虑将.reduce()Map() ,其中映射条目具有基于${carrier_token}:${carrier_name}和所需对象格式的值。 然后使用Array.from().values()的地图。

 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}] const carriers = Array.from( shippingMethodOptions.reduce((map, {carrier_token, carrier_name}) => { const key = `${carrier_token}:${carrier_name}` if (!map.has(key)) map.set(key, { carrier_token, carrier_name }) return map }, new Map()).values() ) console.log(carriers) 

或者,如果只有carrier_token足以实现唯一性,您可以简化它:

 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}] const carriers = Array.from( shippingMethodOptions.reduce((map, {carrier_token, carrier_name}) => { if (!map.has(carrier_token)) map.set(carrier_token, { carrier_token, carrier_name }) return map }, new Map()).values() ) console.log(carriers) 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM