合并json-object并填充next / prev项

时间:2013-07-16 13:04:25

标签: javascript json object for-loop keyframe

我如何预先 - 填充包含一些css-properties的JSON-Object。我需要将所有 not-contained 属性添加到上一个对象,并为所有下一个项目添加相同的内容?

我需要的陈述:

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

例如,我们有一个具有以下样式的元素:

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

以下keyframe - 相似的对象:

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

这里我们需要填充所有以前的项目,在这种情况下:

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

......我们得到这样的东西:

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

...而且,我们需要预先填写所有下一个项目:

  • 2000: top = 100

结果如下:

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

我们的最终目标需要像这样:

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

更新

T.J. Crowder answer到目前为止看起来不错,但问题是我不知道keyframe - 对象中有哪些属性......所以可以,关键帧中有更多/其他属性,而不是widthtop

UPDATE2

目前我有以下内容:

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);
    }
}

似乎

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

但是,如果我通过直接声明它

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

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

两个想法:

  1. 使用原型创建关键帧对象,例如:

    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. 使用for-inspecarticle)和inspec)以手动方式执行操作:

    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遍历对象的可枚举属性的名称。 in检查对象是否具有给定名称的属性(自己的或其原型)。在上面,我假设keyframe内的对象可以继承属性。

    如果您的关键帧对象都来自其他对象(例如,他们的原型不是Object.prototype),那么您需要在其中抛出hasOwnProperty

    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;
            }
        }
    }
    

答案 1 :(得分:1)

这似乎可以满足您的需求:

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}}