0

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.

3
  • (target[i].name your sample objects do not have a "name" property. You probably want this to read (target[i].city Commented Apr 14, 2016 at 23:39
  • @Hamms Sorry. It was a typo. Commented Apr 14, 2016 at 23:40
  • 1
    also note that break will only break out of the innermost for loop, not the both. You probably want to return. Commented Apr 14, 2016 at 23:43

3 Answers 3

3

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;
}
Sign up to request clarification or add additional context in comments.

3 Comments

Isn't .find an ES6 (not ES5) array method?
find isn't supported currently in IE or Opera
My bad. I added a version that doesn't use Array.prototype.find to the answer
1

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>

1 Comment

Code–only answers aren't helpful. You should explain the OP's issue (which isn't clear in the question) and how your answer fixes it. Otherwise you're just a free coding service.
-2

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

4 Comments

No part of this answer actually answers the question. It's just a link to the answer.
My mistake, I thought he wanted to iterate through one object and check if it was present in another object. I may of been mistaken in thinking the answer I provide wasn't helpful. My bad.
It's not that, those are helpful links. But on StackOverflow you can't just post an answer of links. You have to include what the link says and how you can use it to answer the OP's question.
I see, my apologies. Sorry, I will try adhere to this in the future. Thank you for clearing it up for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.