【问题标题】:Adding Unique Objects to Array in JavaScript在 JavaScript 中向数组添加唯一对象
【发布时间】:2018-04-26 20:23:27
【问题描述】:

我有一个名为 Filter 的对象,它存储有关汽车类型的信息。此信息通过 AJAX 检索,并在第一次 ajax 调用时创建对象 0-10 并将其推送到数组。在第二次 ajax 调用中,返回更多汽车类型并将其添加到数组中。

我的问题是:我只想将对象添加到具有唯一标签的数组中。所以对于下一个 AJAX 调用,我只想将带有标签“Hybrid”的对象添加到数组中。这就是我所拥有的,由于某种原因 indexOf 方法似乎不起作用,并且正在将具有相同标签的所有新汽车类型添加到数组中。

代码:

var filter_object = Object.create(Filter);
filter_object.init(label, $(this).val());


if (types.indexOf(filter_object.label) == -1)
   types.push(filter_object);


  var Filter = {
     init: function (label, value) {
        this.label = label;
        this.value = value;
     }
  };

示例对象:

0:   {label: "All Car Types", value: "on"}
1:   {label: "Small Cars", value: "CCAR,ECAR,CDAR,EDAR"}
2:   {label: "Medium Cars", value: "ICAR,SCAR,IDAR"}
3:   {label: "Large Cars", value: "FCAR,PCAR,FDAR"}
4:   {label: "SUVs & Crossovers", value: "IFAR,SFAR,CFAR,RFAR,FFAR,PFAR"}
5:   {label: "Vans", value: "MVAR,RVAR,FVAR"}
6:   {label: "Luxury", value: "LCAR,LDAR"}
7:   {label: "Convertibles", value: "STAR"}
8:   {label: "Sports", value: "SSAR"}
9:   {label: "Commercial", value: "SKAR"}
10:  {label: "Specialty", value: "XXAR"}


// Next AJAX Call
11: {label: "All Car Types", value: "on"}
12: {label: "Small Cars", value: "ECAR,MCAR,CCAR,CDAR,EDAR"}
13: {label: "Hybrids", value: "ICAH,FCAH"}

【问题讨论】:

  • 您不能用其他对象测试对象。它们是不同的实例,因此不相等,即{} != {}
  • 即使可以,将标签传递给indexOf() 也不起作用,因为数组不包含字符串而是对象。另外,为什么不首先使用对象而不是数组,其中标签是键,值是值?这样,密钥是否已经存在都没有关系;它只会被覆盖。
  • 可以看一个物体吗?我只想查看对象的标签与 Types 数组中对象的标签。
  • @Michael 是的,但不是indexOf()。检查你得到的答案。
  • 你能提供更多的代码吗?缺少很多有用的信息。

标签: javascript jquery arrays ajax object


【解决方案1】:

我之前的尝试错过了必须组合值的要求。我仍然不确定您的数据结构,但如果这些可以是收集在数组中的简单对象,那么可能会这样做:

const combineValues = (v1, v2) => {
  const a1 = v1.split(','), a2 = v2.split(',');
  return a1.concat(a2.filter(v => !(a1.includes(v)))).join(',')
}
// combineValues('a,b,c,d', 'a,b,c,e,f') //=> "a,b,c,d,e,f"

const combineTypes = (types, newTypes) => {
  return types.map(type => {
    const matchType = newTypes.find(t => t.label === type.label) || type
    return {label: type.label, value: combineValues(type.value, matchType.value)}
  }).concat(newTypes.filter(type => types.every(t => t.label !== type.label)))
}


const types = [{"label": "All Car Types", "value": "on"}, {"label": "Small Cars", "value": "CCAR,ECAR,CDAR,EDAR"}, {"label": "Medium Cars", "value": "ICAR,SCAR,IDAR"}, {"label": "Large Cars", "value": "FCAR,PCAR,FDAR"}, {"label": "SUVs & Crossovers", "value": "IFAR,SFAR,CFAR,RFAR,FFAR,PFAR"}, {"label": "Vans", "value": "MVAR,RVAR,FVAR"}, {"label": "Luxury", "value": "LCAR,LDAR"}, {"label": "Convertibles", "value": "STAR"}, {"label": "Sports", "value": "SSAR"}, {"label": "Commercial", "value": "SKAR"}, {"label": "Specialty", "value": "XXAR"}]
const newTypes = [{"label": "All Car Types", "value": "on"}, {"label": "Small Cars", "value": "ECAR,MCAR,CCAR,CDAR,EDAR"}, {"label": "Hybrids", "value": "ICAH,FCAH"}]


const updated = combineTypes(types, newTypes)
console.log(updated)

请注意,这会结合“Small Cars”中的值并添加“Hybrids”。它不会改变您的任何数据,而是使用新对象创建一个新数组。

为了代码的简单性,包含了一些愚蠢的低效率。当没有找到匹配的新类型时,我们在一个类型及其自身上调用combineValues,显然没有用。虽然解决这个问题并不难,但代码会更难看。考虑到可能的元素数量,我无法想象这会有问题。

【讨论】:

  • 嗨,Scott - 我在用我的实际代码实现您的解决方案时遇到了一些麻烦。到目前为止,这是我所拥有的:prntscr.com/jazly7 ...我添加了一条评论,其中描述了它在做什么以及我想要实现的目标。让我知道你是否能提供帮助。非常感谢!!!
  • 这段代码解决了只添加唯一标签prntscr.com/jazp8i的问题,但没有解决添加所有唯一值的问题(例如MCAR)
  • 没有看到你的 HTML 我真的没有这个感觉。如果你让它工作,太好了!下次您想在这里共享代码时,如果可以,请将其放在问题中,最好是在 sn-p 中。如果太多,请使用 CodePen、JSFiddle 或 JSBin 之类的东西。它使协作变得更加容易。
【解决方案2】:

你应该使用 es6 的.some

if (!types.some(e=> e.label === filter_object.label))
 types.push(filter_object);

注意:some() 方法测试数组中的至少一个元素是否通过了提供的函数实现的测试。 Here

【讨论】:

  • 你的意思正好相反? :)
  • 太棒了,这正是我想要的。谢谢! :)
  • 很高兴知道这一点。考虑接受答案-:)
  • @GeorgeBailey 我可以使用 some() 检查同一个标签是否具有不同的或新的/值?例如:在小型汽车的第二次 AJAX 调用中......有一个新值 MCAR。想知道是否可以使用 some() 查看以前的 Small Cars 值(“CCAR,ECAR,CDAR,EDAR”),然后将 MCAR 插入此处。
  • 点赞e=> e.label === filter_object.label && e.values === filter_object.values
【解决方案3】:

您可以创建一个包含所有现有标签的新数组作为查找,然后在传入数组上调用.reduce,如下所示:

const existingLabels = existing.map(item => item.label);

const updated = newItems.reduce((all, item) => {
  if (!existingLabels.includes(item.label))
      all.push(item);

  return all;
}, existing);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    • 2016-02-06
    • 1970-01-01
    相关资源
    最近更新 更多