【问题标题】:js array.IndexOf not working with objects?js array.IndexOf 不适用于对象?
【发布时间】:2016-05-14 18:27:18
【问题描述】:

我正在尝试创建一个包含日期和时间的对象的数组。我正在循环一个可能有重复的源,所以我想每次检查我还没有存储当前日期和时间。

但是,我总是以重复结束。所以我认为 array.indexOf 可能不适用于对象?

    movies.forEach(function(movie){
        if (days.indexOf(movie.day) !== -1) { //if the movie's day exists in our array of available days...
            possibleMovies.push(movie);

            //create a day/time object for this movie
            dt = {day: movie.day, time: movie.time};

            //unless we already have this day and time stored away, do so
            if (possibleTimes.indexOf(dt) === -1) {
                possibleTimes.push(dt);
            }

        }
    });

循环完成后可能的时间:

[ { day: '01', time: '18:00' },
  { day: '01', time: '16:00' },
  { day: '01', time: '18:00' },
  { day: '01', time: '16:00' } ]

我希望第三和第四行不在那里......

--------- 更新 ----------

我变了

dt = {day: movie.day, time: movie.time};

进入这个

dt = JSON.stringify({day: movie.day, time: movie.time});

它按预期工作。一旦我检索到数据,只需要 JSON.parse。

【问题讨论】:

  • 对象是通过引用来比较的,而不是它们的内容。
  • 哦,谢谢。我只是尝试对其进行字符串化,然后它按预期工作,您刚刚解释了原因 =)
  • 你应该看看 www.lodash.com
  • @MattWelander 小心串连。这是一个相对昂贵的操作,您可能只想迭代和测试过滤属性。如果性能很关键,请考虑运行一些性能测试。

标签: javascript arrays object javascript-objects indexof


【解决方案1】:

根据MDN

indexOf() 使用 严格相等(与 === 或三等号运算符使用的方法相同)将 searchElement 与 Array 的元素进行比较。

这就是为什么 possibleTimes.indexOf 总是导致 -1。

【讨论】:

    【解决方案2】:

    如果两个对象指向相同的位置,则认为它们相等。

    var obj1 = { x: 100 };
    var obj2 = obj1;
    console.log( obj1===obj2 );     //  outputs true
    
    var obj1 = { x: 100 };
    var obj2 = { x: 100 };
    console.log( obj1===obj2 );     //  outputs false
    

    您可以使用JSON.stringify 将每个对象转换为字符串,然后进行比较。请记住,属性的顺序必须匹配。

    console.log( JSON.stringify( obj1 ) === JSON.stringify( obj2) );    //outputs true
    

    【讨论】:

      【解决方案3】:

      如果您愿意使用Ramda,它会变得超级简单:

      let a = [
        { day: '01', time: '18:00' },
        { day: '01', time: '16:00' },
        { day: '01', time: '18:00' },
        { day: '01', time: '16:00' }
      ];
      
      let b = R.uniq(a);
      console.log(b);
      

      http://jsbin.com/ligihexate/edit?js,console

      【讨论】:

      • “它变得超级简单” --- 你的代码并没有产生正确的结果。
      • @zerkms 我假设您实际上并没有阅读我发布的代码,只是运行了 JS Bin。当我开始使用 ES6 Set 对象时,它一定已经被修改过。被注释的两行...取消注释。
      • 我已经更新了 JS Bin 示例。对困惑感到抱歉。我已经很久没有使用它了。
      猜你喜欢
      • 2014-02-23
      • 2012-05-18
      • 1970-01-01
      • 2021-04-28
      • 1970-01-01
      相关资源
      最近更新 更多