Javascript映射集合

时间:2018-07-22 19:31:54

标签: javascript collections

问题:

我正在尝试构建一个简单的搜索工具。它通过将一个ID与另一个具有相同ID的项目匹配来返回搜索查询。不用太复杂,我遇到的问题是,当我以前组织数据时,来自javascript的map函数完美地返回了所有结果。但是,现在我的数据结构有所不同(我认为是一个集合吗?).... id似乎没有排列整齐,从而导致显示错误的搜索结果。

有问题的功能

const options = this.props.itemIds.map((id) => (
  <Option key={this.props.itemSearchList[id].id}>
     {this.props.itemSearchList[id].name}
  </Option>
));

当数据的结构如下所示时:

以前的结构示例:

const items = [
  {
    id: 0,
    name: "name 0",
    tags: ['#sports', '#outdoor', '#clothing'],
  },
  {
    id: 1,
    name: "name 1",
    tags: ['#sports', '#outdoor', '#clothing'],
  },
  {
    id: 2,
    name: "Name 2",
    tags: ['#sports', '#outdoor', '#clothing'],
  },

现在数据是一个集合,...地图功能无法按预期运行,并且返回的结果不正确或根本不返回:我已经能够使用lodash地图过去曾经成功地在这种结构上起作用。

以下是新数据的屏幕截图:

enter image description here

我相信写出示例的代表性方法是:

const newItems = [
  0: {
    id: 0,
    name: "name here",
  },
  1: {
    id: 1,
    name: "name here",
  },
]

是否有任何建议使这项工作有效或需要更多信息?也许我完全误解了这个问题,但是我认为这与JS的数据结构和map函数有关。我可以看到结果返回了,但是ID不再正确排列了。

这是未对准的视觉表示。橙色是搜索输入,它可以获取正确的结果。绿色是由于数据结构和映射(我认为)而导致的实际显示不对齐。

enter image description here

3 个答案:

答案 0 :(得分:1)

您所说的“集合”和“地图”实际上是数组。现在,其中一个数组的对象恰好在数组中与id匹配的位置:

items[5].id === 5

现在通过排序/变异/无论您更改顺序如何,以使位于特定位置的元素都不会将其作为id:

newItems[5].id // 7 :(

这意味着您将无法再访问那么简单的项目,现在您必须再次对数组进行排序以使其井然有序,或者您要搜索具有ID的对象:

newItems.find(item => item.id === 5) // { id: 5, ... }

或者您切换到一些未排序的集合,例如真实的Map

const itemsMap = new Map(newItems.map(item => ([item.id, item])));

因此,您可以获得其ID为:

itemsMap.get(5) // { id: 5, ... }

...但是整个事情与Array.prototype.map完全无关。

答案 1 :(得分:1)

问题是您正在使用索引,并将ID与ID对齐作为一种伪键,这超出了脆弱性。您应该做的 是通过id进行键控(意味着items应该是一个对象),然后有一个单独的数组来存储所需的顺序。因此items将是一个以id为键的对象:

const items = {
  1: {
    id: 1,
    name: "name 1",
    tags: ['#sports', '#outdoor', '#clothing'],
  },
  2: {
    id: 2,
    name: "name 2",
    tags: ['#sports', '#outdoor', '#clothing'],
  },
  9: {
    id: 9,
    name: "Name 9",
    tags: ['#sports', '#outdoor', '#clothing'],
  },
};

然后itemIds(看来已经存在)是一个具有正确顺序的数组:

const itemIds = [1,9,2];

然后可以通过遍历该数组并通过所述键获取元素来以正确的顺序访问它们:

itemIds.map((id) => {
  const item = items[id];
  // do something with the item
}

看看Redux如何建议归一化状态形状。

https://redux.js.org/recipes/structuring-reducers/normalizing-state-shape

答案 2 :(得分:0)

这是我的简单解决方案:

const options = [];
    this.props.itemList.forEach((item) => {
      if (this.props.searchResults.includes(item.id)) {
        options.push(<Option key={item.id}>{item.name}</Option>);
      }
    });

让我知道您的想法(向试图帮助的小组!)