3

I am a JS beginner and am doing basic tutorials. I am trying to perform a zip function to return a list of {videoID: bookmarkID}. So take for example:

var videos = [
        {
            "id": 70111470,
            "title": "Die Hard"
        },
        {
            "id": 654356453,
            "title": "Bad Boys"
        },
        {
            "id": 65432445,
            "title": "The Chamber"
        }
    ],
    bookmarks = [
        {id: 470, time: 23432},
        {id: 453, time: 234324},
        {id: 445, time: 987834}
    ];
}

This does not work (I get unexpected token '.'):

return Array.zip(videos,bookmarks, function(v, b){
  return {v.id: b.id};
});

This does, but returns a list containing {'v': bookmarkID}:

return Array.zip(videos,bookmarks, function(v, b){
  return {v: b.id};
});

How do I get the video ID to be the key for the value bookmarkID? Also, are these technically maps or objects? Thanks.

2
  • how are the two id mapped together? with the last three digits? Commented Nov 12, 2016 at 10:05
  • 1
    Just simply in the order of the list, so the first video id with the first bookmark id and so forth. Commented Nov 12, 2016 at 10:08

3 Answers 3

8

Try:

return Array.zip(videos,bookmarks, function(v, b){
  return {[v.id]: b.id};
});
Sign up to request clarification or add additional context in comments.

3 Comments

This is what I'm looking for! Could you explain why this works or why mine does not? The zip implementation just loops through both arrays and runs the function on each element in the left and right lists, so why can't I pass the ID in both?
I didn't know this one, nice!
This is actually a new JS feature which comes with the new ES6, its name is Computed Property Names
2

You could map one and get the elemnt of the other with the same index.

var videos = [{ "id": 70111470, "title": "Die Hard" }, { "id": 654356453, "title": "Bad Boys" }, { "id": 65432445, "title": "The Chamber" }],
    bookmarks = [{ id: 470, time: 23432 }, { id: 453, time: 234324 }, { id: 445, time: 987834 }],
    zipped = videos.map(function (v, i) {
        var o = {};
        o[v.id] =  bookmarks[i].id;
        return o;
    });

console.log(zipped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

ES6

var videos = [{ "id": 70111470, "title": "Die Hard" }, { "id": 654356453, "title": "Bad Boys" }, { "id": 65432445, "title": "The Chamber" }],
    bookmarks = [{ id: 470, time: 23432 }, { id: 453, time: 234324 }, { id: 445, time: 987834 }],
    zipped = videos.map((v, i) => ({ [v.id]: bookmarks[i].id }));

console.log(zipped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

1 Comment

This returns { videoID: v.id, bookmarkID: bookmarks[i].id } and I'm looking for {v.id: bookmark.id}
0

Your first attempt doesn't work because the key of the object you used is not correct. When you use object literals to define an object, keys have to be numeric or string literals.

On the other hand, you could solve that problem using array-like notation to create that key in the object. In JS there are two ways of accessing the value of a key within an object: using dot notation or array-like notation. The array-like notation allows you to access keys of an object not determined until runtime (keys that are variables). For instance:

var obj = {};
for(var i = 0; i < 3; i++)
  obj[i] = i + 1;
console.log(obj);

In case you're interested, there isn't much difference in terms of performance between the two.

Getting back to your problem. Zip is a function that, in words of functional programmers, takes a pair of lists and creates a list of pairs. From my point of view (and a functional point of view I think), it might be wiser to tackle it differently from what you've done.

For instance (and just as a quick idea), you could create a function that does the zip (typical zip) and apply to the result to another function that picks the values you're interested in:

var videos = [{
    "id": 70111470,
    "title": "Die Hard"
  }, {
    "id": 654356453,
    "title": "Bad Boys"
  }, {
    "id": 65432445,
    "title": "The Chamber"
  }],
  bookmarks = [{
    id: 470,
    time: 23432
  }, {
    id: 453,
    time: 234324
  }, {
    id: 445,
    time: 987834
  }];

// Assuming same size.
function zip(list1, list2) {
  return list1.length ?
    [[list1[0], list2[0]]].concat(zip(list1.slice(1), list2.slice(1))) : [];
}

function makeObj(list) {
  var obj = {};
  obj[list[0].id] = list[1].id;
  return obj;
}

console.log(zip(videos, bookmarks).map(makeObj));

I made a simple zip using recursion (there are optimal ways to do it, and also can be done taking into account that the lists can have different sizes) but I think it can help you to grasp the idea.

Hope it helps

1 Comment

Thanks for the thorough explanation; it was really helpful!

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.