javascript比较数组中的对象

发布于 2024-11-08 15:03:51 字数 2082 浏览 0 评论 0原文

我在页面上有一个图片网格。而且,我想定期将一个对象随机交换为对象数组中 50 个对象中的一个,但前提是它们尚未位于网格中。最后一部分是我的代码未能做到的。

我首先获取所有 50 个项目,并将它们放入一个 allmedia 数组中:

// initialize
var allmedia = getAllMedia();
var imagesInGrid = [];

当我将这些项目放入网格中时,我将添加到一个网格项目数组中:

imagesInGrid.push(allmedia [i]); // while looping to fill DOM grid

然后,每 8 秒我运行一个 getRandomImage() 例程来随机获取图像从 allmedia 数组中获取,然后测试它以查看它是否尚未在 DOM 中。

function getRandomImageNotInGrid(){
    var randomNumber = Math.floor(Math.random() * allmedia.length);
    if (!isInArray(allmedia[randomNumber], imagesInGrid)) {
        return allmedia[randomNumber];
    } else {
        return getRandomImageNotInGrid();
    }
}

function isInArray(item, arr) {
    if(arr[0]===undefined) return false;
    for (var i=arr.length;i--;) {
        if (arr[i]===item) {
            return true;
        }
    }
    return false;
}

但是当我单步执行代码时 (arr[i]===item) 测试失败。我可以看到这两个对象完全相同,但 === 并不认为这是真的。

这是 ByReference / ByValue 问题吗?我做错了什么?

console.log:

arr[i]===item
false
arr[i]==item
false
typeof item
"object"
typeof arr[i]
"object"

编辑::

在下面的输出中,我不明白为什么 arr[0] 与“item”不同。我使用与放入 allmedia 中的对象完全相同的对象,就像将项目放入页面中一样,并相应地更新 imagesInGrid。

console.dir(arr[0]);
    Object
        caption: Object
        comments: Object
        created_time: "1305132396"
        filter: "Poprocket"
        id: "69204668"
        images: Object
        likes: Object
        link: "http://instagr.am/p/EH_q8/"
        location: Object
        tags: Array[2]
        type: "image"
        user: Object
        __proto__: Object

console.dir(item);
    Object
        caption: Object
        comments: Object
        created_time: "1305132396"
        filter: "Poprocket"
        id: "69204668"
        images: Object
        likes: Object
        link: "http://instagr.am/p/EH_q8/"
        location: Object
        tags: Array[2]
        type: "image"
        user: Object
        __proto__: Object

I have a grid of pictures on a page. And, periodically, I want to randomly swap one out for one of 50 I have in an array of Objects- but only if they're not already in the grid. This last part is what my code is failing to do.

I first get all 50 items, and put them into an allmedia array:

// initialize
var allmedia = getAllMedia();
var imagesInGrid = [];

When I place the items in the grid, I add to an array of grid items:

imagesInGrid.push(allmedia [i]); // while looping to fill DOM grid

Then, every 8 seconds I run a getRandomImage() routine that randomly gets an image from the allmedia array and then tests it to see if it's not already in the DOM.

function getRandomImageNotInGrid(){
    var randomNumber = Math.floor(Math.random() * allmedia.length);
    if (!isInArray(allmedia[randomNumber], imagesInGrid)) {
        return allmedia[randomNumber];
    } else {
        return getRandomImageNotInGrid();
    }
}

function isInArray(item, arr) {
    if(arr[0]===undefined) return false;
    for (var i=arr.length;i--;) {
        if (arr[i]===item) {
            return true;
        }
    }
    return false;
}

But when I step through the code the (arr[i]===item) test is failing. I can see that the two objects are exactly the same, but the === isn't seeing this as true.

Is this a ByReference / ByValue issue? What am I doing wrong?

console.log:

arr[i]===item
false
arr[i]==item
false
typeof item
"object"
typeof arr[i]
"object"

Edit::

In the output below, I don't understand why arr[0] is not the same as 'item'. I use the exact same object that I put into allmedia as I do when I place the item into the page and, accordingly update imagesInGrid.

console.dir(arr[0]);
    Object
        caption: Object
        comments: Object
        created_time: "1305132396"
        filter: "Poprocket"
        id: "69204668"
        images: Object
        likes: Object
        link: "http://instagr.am/p/EH_q8/"
        location: Object
        tags: Array[2]
        type: "image"
        user: Object
        __proto__: Object

console.dir(item);
    Object
        caption: Object
        comments: Object
        created_time: "1305132396"
        filter: "Poprocket"
        id: "69204668"
        images: Object
        likes: Object
        link: "http://instagr.am/p/EH_q8/"
        location: Object
        tags: Array[2]
        type: "image"
        user: Object
        __proto__: Object

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

西瓜 2024-11-15 15:03:51

您可以从所有媒体中删除一个,而不是从所有媒体中随机选择一个吗?

var randomNumber = Math.floor(Math.random() * allmedia.length);
imagesInGrid.push(allmedia.splice(randomNumber,1));

Instead of randomly selecting one from allmedia, can you instead remove one from allmedia?

var randomNumber = Math.floor(Math.random() * allmedia.length);
imagesInGrid.push(allmedia.splice(randomNumber,1));
绮烟 2024-11-15 15:03:51

当您使用 === 时,您是通过引用来比较对象。您使用什么类型的对象进行比较?您确定它们是同一个对象引用吗?例如,如果您使用字符串,则可能需要使用 == 而不是 ===。如果您使用 DOM 对象,您将需要比较源,正如 Alxandr 建议的那样。

另外,您的 for 循环语法似乎是错误的:

for (var i=arr.length;i--;)

应该是:

for (var i=arr.length - 1; i >= 0; i--)

...如果我没有记错的话。

When you use ===, you are comparing the objects by reference. What type of objects are you using to compare? Are you sure they are the same object reference? For example, if you are using strings, you may want to use == instead of ===. If you are using DOM objects, you will want to compare the source, as Alxandr suggested.

Also, your for loop syntax appears to be wrong:

for (var i=arr.length;i--;)

Should be:

for (var i=arr.length - 1; i >= 0; i--)

...if I'm not mistaken.

我乃一代侩神 2024-11-15 15:03:51

您没有显示任何有关如何创建图像“对象”或如何在 DOM 中添加和删除它们的代码。如果您要创建图像元素并将引用存储在数组中,然后将 DOM 元素替换为数组中的元素,则比较应该可以进行。

但是,如果您的图像对象是用于创建用于显示的图像元素的一组数据,那么它们将永远不会彼此相等。每个 javascript 对象都是唯一的,它只会等于它自己。

但我怀疑最简单的解决方案是 ic3b3rg 建议的 - 当您选择对象时从 allMedia 中删除该对象,这样您就不必测试它是否已经在 imagesInGrid 中因为每个图像只能选择一次。如果您希望显示永远持续下去,那么当 allmedia 为空时,将 imagesInGrid 中的所有图像放回其中并重新开始。

编辑

你的问题是 for 循环。当您设置时:

for (var i=arr.length;i--;) {
  // On first iteration, i=arr.length
  // so arr[i] is undefined
}

i 在第一个循环之后之前不会递减,因此设置 i=arr.length-1。更常见的是使用 while 和递减计数器:

var i = arr.length;
while (i--) {
  // i is decremented after the test
}

You don't show any code for how the image "objects" are created or how they are added and removed from the DOM. If you are creating image elements and storing references in an array, then replacing the DOM element with the one from the array, then the comparision should work.

However, if your image object is a bundle of data that is used to create an image element for display, then they will never be equal to each other. Every javascript object is unique, it will only ever be equal to itself.

But I suspect the simplest solution is that suggested by ic3b3rg - remove the object from allMedia when you select it, that way you don't have to test if it's already in imagesInGrid because you can only select each image once. If you want the display to go on forever, then when allmedia is empty, put all the images from imagesInGrid back into it and start again.

Edit

Your problem is the for loop. When you set :

for (var i=arr.length;i--;) {
  // On first iteration, i=arr.length
  // so arr[i] is undefined
}

i is not decremented until after the first loop, so set i=arr.length-1. It is more common to use while with a decrementing counter:

var i = arr.length;
while (i--) {
  // i is decremented after the test
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文