Merge json-object and populate next/prev items

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-13 04:36:37

问题


How can I pre-populate an JSON-Object which contains some css-properties. Where I need to add all not-contained properties to the previous object and the same for all next up items?

The statement I need:

if (property is not in object) object[property] = $('.foo').css(property);

We have for example an element with the following styling:

.foo {
    top: 0;
    width: 100px;
}

And the following keyframe-alike object:

var keyframe = {
    0: {
        top: 0
    },
    1000: {
        top: 100
    },
    2000: {
        width: 100
    }
};

Here we need to populate all previous items, in this case:

  • 0: width = 0
  • 1000: width = 0

...we get something like this:

var keyframe = {
    0: {
        top: 0,
        width: 0
    },
    1000: {
        top: 100,
        width: 0
    },
    2000: {
        top: 100,
        width: 100
    }
};

...and further, we need to prefill all next items:

  • 2000: top = 100

What results in:

var keyframe = {
    0: {
        top: 0
    },
    1000: {
        top: 100
    },
    2000: {
        top: 100,
        width: 100
    }
};

Our final object needs to be like this one:

var keyframe = {
    0: {
        top: 0,
        width: 0
    },
    1000: {
        top: 100,
        width: 0
    },
    2000: {
        top: 100,
        width: 100
    }
};

Update

T.J. Crowder answer looks good so far, however the problem is that I don't know what properties are in the keyframe-object... So it can be, that there are more/other properties in the keyframe than width and top.

Update2

Currently I've the following:

var $foo = $('.foo');
for (var key in keyframe) {
    var obj = keyframe[key];
    for(var ok in obj) {
        if (!(ok in obj)) obj[ok] = $foo.css(ok);
    }
}

But it seems that

if (!(ok in obj)) // is always `truthy`

however if I do it by declaring it directly

if (!('top' in obj)) // it works...

Any ideas?


回答1:


This appears to do what you want:

var all = {};

$.each(keyframe, function(_, obj) {
    $.each(obj, function(k) {
        all[k] = 0;
    });
});

$.each(keyframe, function(_, obj) {
    $.each(all, function(k) {
        if(k in obj)
            all[k] = obj[k];
        else
            obj[k] = all[k];
    });
});

console.log(keyframe)
// {"0":{"top":0,"width":0},
// "1000":{"top":100,"width":0},
// "2000":{"width":100,"top":100}}



回答2:


Two thoughts:

  1. Create your keyframe objects with a prototype behind them, e.g.:

    var proto = {top: 0, width: 100};
    var keyframe = {
        0:    Object.create(proto),  // Inherits everything
        1000: Object.create(proto, { // Inherits only width
                  top: {value: 100}
              },
        2000: Object.create(proto, { // Inherits only top
                  width: {value: 100}
              })
    };
    
  2. Do it the manual way, using for-in (spec, article) and in (spec):

    var obj, key;
    for (key in keyframe) {
        obj = keyframe[key];
        if (!('top' in obj)) {
            obj.top = 0;
        }
        if (!('width' in obj)) {
            obj.width = 100;
        }
    }
    

    for-in loops through the names of the enumerable properties of the object. in checks to see if an object as a property with a given name (its own, or on its prototype). In the above, I assumed it was okay for the objects within keyframe to inherit properties.

    If your keyframe objects are every derived from other objects (e.g., they have something other than Object.prototype as their prototype), you'll want to throw a hasOwnProperty in there:

    var obj, key;
    for (key in keyframe) {
        if (keyframe.hasOwnProperty(key)) {
            obj = keyframe[key];
            if (!('top' in obj)) {
                obj.top = 0;
            }
            if (!('width' in obj)) {
                obj.width = 100;
            }
        }
    }
    


来源:https://stackoverflow.com/questions/17677311/merge-json-object-and-populate-next-prev-items

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