Comparing two arrays of objects for duplicate objects and push it when it's not a duplicate in JavaScript

大城市里の小女人 提交于 2019-12-12 01:38:09

问题


This question might be too similar to this question I asked a few hours ago, but the issue I was struggling with is actually more complex than I initially thought. I was not aware of the fact that no two objects can be considered to be same in JavaScript even when the two objects have the same set of properties and values.

I have two arrays of objects like this in JavaScript.

var from = [
    {city: "seoul", country: "korea"},
    {city: "tokyo", country: "japan"},
    {city: "beijing", country: "china"},
    {city: "new york", country: "usa"}
];
var to = [
    {city: "seoul", country: "korea"},
    {city: "tokyo", country: "japan"},
    {city: "toronto", country: "canada"}
];

What I want to do is to check if any of the objects in the "from" array is already in the "to" array and push the object to the "to" array only when it is not in the "to" array, and I want to add only one object from the "from" array to the "to" array even if there are other objects in the "from" array that are not in "to" array. In other words, I want to break out of a loop as soon as an object is pushed to the "to" array.

In the end, I want the "to" array to look like this.

var target = {
    {city: "seoul", country: "korea"},
    {city: "tokyo", country: "japan"},
    {city: "toronto", country: "canada"},
    {city: "beijing", country: "china"}
};

Here is a function that I came up with to achieve this effect.

function ruthere (source, target) {
    for (var i = 0; i < target.length; i++) {
        for (var j = 0; j < source.length; j++) {
            if (target[i].city == source[j].city) {
                console.log("Already there");
            } else {
                target.push(source[j]);
                i = target.length-1;
                break;
            }
        }
    }
}

This is as far as I've gotten to achieve the result I wanted, but this still does not do what I want.

*edit: I only need to check if the value of the name property of an object is the same. The value of country property does not have to be the same.


回答1:


A few things wrong with your code: you do need a nested loop, but not for why you're doing it here. If the cities in the target array aren't exactly the same as those in the source array, then some may never get pushed to the target array. Cities can also have the same name but be in different countries.

Assuming you can use ES5 features:

function ruthere(source, target) {
    for (var i = 0; i < source.length; i++) {
        var srcObj = source[i];
        var tarObj = target.find(function (obj) {
            return obj.city === srcObj.city && obj.country === srcObj.country;
        });

        if (!tarObj) {
            target.push(srcObj);
            break;
        }
    }

    return target;
}

Edit: I'm mistaken, Array.prototype.find is ES6, not ES5. Here's the ES3 version:

function ruthere(source, target) {
    for (var i = 0; i < source.length; i++) {
        var srcObj = source[i];
        var tarObj;
        for (var j = 0; j < target.length; j++) {
            var obj = target[j];
            if (srcObj.city === obj.city && srcObj.country === obj.country) {
                tarObj = obj;
                break;
            }
        }

        if (!tarObj) {
            target.push(srcObj);
            break;
        }
    }

    return target;
}



回答2:


Just use;

var from = [{
    city: "seoul",
    country: "korea"
}, {
    city: "tokyo",
    country: "japan"
}, {
    city: "beijing",
    country: "china"
}, {
    city: "new york",
    country: "usa"
}];
var to = [{
    city: "seoul",
    country: "korea"
}, {
    city: "tokyo",
    country: "japan"
}, {
    city: "toronto",
    country: "canada"
}];

function ruthere(source, target) {
    for (var i = 0; i < source.length; i++) {
        if (source[i].city !== target[i].city) {
            target.push(source[i])
        }
    }
    for (var i = 0; i < target.length; i++) {
		$(".city").append((i + 1) + " " + target[i].city + "<br>")
    }
}
ruthere(from, to)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="city"></div>



回答3:


I would look into using underscore to help you achieve this: Underscore.js

This answer will probably be a very helpful answer: https://stackoverflow.com/a/28632359/5768113



来源:https://stackoverflow.com/questions/36635822/comparing-two-arrays-of-objects-for-duplicate-objects-and-push-it-when-its-not

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!