简体   繁体   English

使用字典映射 API 响应并创建对象数组,尝试删除重复项

[英]Using dictionary to map against an API response and create array of objects, trying to remove duplicates

I have a React component that I'm using a dictionary inside of to compare against an API response for address state, and map only the states that are returned back as options in a dropdown.我有一个 React 组件,我在其中使用字典来比较地址状态的 API 响应,并仅映射作为下拉列表中的选项返回的状态。

This is the mapping function I'm using to create the array of returned states:这是我用来创建返回状态数组的映射函数:

let activeStates = props.locations.map(x => ({abbr: x.address.state, name: states[x.address.state]as string}));

Against my dictionary which looks like this:对照我的字典,它看起来像这样:

const states = {
  AL: "Alabama",
  AK: "Alaska",
  AZ: "Arizona",
  AR: "Arkansas",
  CA: "California",
  CO: "Colorado",
  (all US states are included)
};

And that creates an array of all the location addresses in a response like this:这会在响应中创建一个包含所有位置地址的数组,如下所示:

3:
abbr: "3"
name: {abbr: "TN", name: "Tennessee"}
__proto__: Object
4:
abbr: "4"
name: {abbr: "WI", name: "Wisconsin"}
__proto__: Object
5:
abbr: "5"
name: {abbr: "NC", name: "North Carolina"}
__proto__: Object
6:
abbr: "6"
name: {abbr: "NC", name: "North Carolina"}

That feeds my Component where I'm mapping the array to the dropdown:这为我将数组映射到下拉列表的组件提供了信息:

<select value={state} onChange={handleStateChange}>
  <option value={''}>All</option>
    {activeStates.map((state) => (
  <option value={state.abbr}>{state.name}</option>))}
</select>

I'm trying to write a function that works off of activeStates to create a new array of only one of each state/abbreviation instead of producing duplicates.我正在尝试编写一个使用activeStates的函数来创建每个状态/缩写中只有一个的新数组,而不是生成重复项。 I know that because all of the values returned in that mapped array are considered unique I need to run an indexing function to get rid of the duplicates, but I'm not sure how.我知道因为该映射数组中返回的所有值都被认为是唯一的,所以我需要运行一个索引函数来消除重复项,但我不确定如何。

So far I've used:到目前为止,我已经使用了:

let statesObj = props.locations.reduce((acc, curr) => {
   acc[curr.address.state] = states[curr.address.state];
   return acc;
}, {});


  let uniqueStates = Object.entries(statesObj).map(([abbr, name]) => ({abbr, name }));
  let activeStates = props.locations.map(x => ({abbr: x.address.state, name: states[x.address.state]}));
  let uniqueStates = new Set(activeStates);
  let uniqueStatesArray = [...uniqueStates]

and

let activeStates = Array.from(new Set(props.locations.map(x => ({ abbr: x.address.state, name: states[x.address.state]})))

None of which have worked.这些都没有奏效。

You are on the right track.你走在正确的轨道上。

When adding objects to a Set it is by reference:将对象添加到 Set 时,它是通过引用:

const s = new Set()
const o = { a: 1, b: 2 }

s.add(o)

console.log(s.has(o)) // true
console.log(s.has({ a: 1, b: 2 })) // false

This can lead to other effects you might not anticipate:这可能会导致您可能无法预料的其他影响:

const s = new Set()
s.add({ a: 1, b: 2 })
s.add({ a: 1, b: 2 })
s.add({ a: 1, b: 2 })

console.log(s) // Set { { a: 1, b: 2 }, { a: 1, b: 2 }, { a: 1, b: 2 } }

To answer your question, you can use one of the object's properties to add to a set you use for checking:要回答您的问题,您可以使用对象的属性之一添加到用于检查的集合中:

const dropDuplicates = arr => {
  const seen = new Set()
  const result = []

  for (let obj of arr) {
    if (!seen.has(obj.abbr)) { // check if `abbr` has been seen
      result.push(obj) // if not, then add state to result
      seen.add(obj.abbr) // this state is now seen, don't add anymore
    }
  }

  return result
}

I ended up working it out by chaining a few mapping functions together with a filter like:我最终通过将一些映射函数与过滤器链接在一起来解决它,例如:

  let activeStates = props.locations.map(x => ({abbr: x.address.state, name: states[x.address.state]as string}));

  function getUnique(activeStates, comp) {

    const unique = activeStates
      .map(e => e[comp])
      // store the keys of the unique states
      .map((e, i, final) => final.indexOf(e) === i && i)
      // eliminate the duplicate keys and store unique states
      .filter(e => activeStates[e]).map(e => activeStates[e]);
     return unique;
  }

  let uniqueStates = getUnique(activeStates, 'abbr')

A bit of a roundabout but it ended up working and now all the options are mapping correctly.有点迂回,但最终成功了,现在所有选项都正确映射。 Thanks everyone for the great suggestions!谢谢大家的好建议!

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

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