Home  >  Q&A  >  body text

javascript - How to use a variable as the key of an object and push it into an array?

The keys of a and b are all equal

diffObject(a, b) {
    let before = [], after = []
    Object.keys(a).forEach(key => {
        if (a[key] !== b[key]) {
            before.push({ ??? }) // 这里应该怎么写,{key: a[key]},但key不能是变量啊
            after.push({ ??? })
        }
    })
    return [before, after]
}

Or is there any better, more efficient, more awesome way?

The effect I want to achieve is this

const ob1 = {
    name: '辣条',
    color: '绿色',
    length: 10,
}
const ob2 = {
    name: '辣条',
    color: '黄色',
    length: 12,
}
const diff = diffObject(ob1, ob2)
console.log('diff[0]:', diff[0])
console.log('diff[1]:', diff[1])
//  diff[0]: [{color: '绿色'}, {length: 10,}]
//  diff[1]: [{color: '黄色'}, {length: 12,}]

The root of this problem is how to use a variable as a key when declaring an object.

世界只因有你世界只因有你2663 days ago1498

reply all(4)I'll reply

  • PHP中文网

    PHP中文网2017-07-05 11:02:13

    ES6 allows literals to be used when defining objects, using expressions as property names of objects

    var lastWord = 'last word';
    
    var a = {
      'first word': 'hello',
      [lastWord]: 'world'
    };
    
    a['first word'] // "hello"
    a[lastWord] // "world"
    a['last word'] // "world"

    reply
    0
  • 淡淡烟草味

    淡淡烟草味2017-07-05 11:02:13

    Answer after modifying the question description

    The root of this problem is how to use a variable as a key when declaring an object

    If the variable is a string or number

    var o = {}; 
    var a = 'aaa'; 
    
    o[a] = '用变量的值做 key'; 
    
    console.log(o); 

    If the variable is an object

    Then we need to use ES6 Map

    Look at the code. It’s easy to understand. It’s a superset of the previous method

    var key = { val: '我是对象 作为key' }; 
    
    // 初始化一个 m  类比 s = new Object(); 
    var m = new Map(); 
    m.set(key, '被key射中(作为值'); 
    

    ScreenShot


    New writing method

    const ob1 = {
        name: '辣条',
        color: '绿色',
        length: 10,
    }
    const ob2 = {
        name: '辣条',
        color: '黄色',
        length: 12,
    }
    const diff = diffObject(ob1, ob2)
    console.log('diff[0]:', diff[0])
    console.log('diff[1]:', diff[1])
    //  diff[0]: [{color: '绿色'}, {length: 10,}]
    //  diff[1]: [{color: '黄色'}, {length: 12,}]

    Utilize reduce

    var diffObj = (a, b) => (
        Object.keys(a).reduce((acc, key) => {
            if (a[key] !== b[key]){
                let temp = {}; 
                temp[key] = a[key]; 
                acc[0].push(temp);
    
                temp = {}; 
                temp[key] = b[key]; 
                acc[1].push(temp); 
                
                return acc; 
            } else {
                return acc; 
            }
        }, [[], []])
    );

    ScreenShot


    Before modification

    diffObject(a, b) {
        let before = [], after = []
        Object.keys(a).forEach(key => {
            if (a[key] !== b[key]) {
                before.push({ ??? }) // 这里应该怎么写,{key: a[key]},但key不能是变量啊
                after.push({ ??? })
            }
        })
        return [before, after]
    }

    Achieved

    Uh-huh. . After reading the problem description for a long time, I’m not quite sure what you want to do

    Let’s guess based on the function name and before after. Do you want to put the different attributes and values ​​of object a and object b into before and after respectively? If so, you can take a look at the code below

    
    var diffObj = (a, b) => {
        let keys = []
          , vals = []; 
          
        Object.keys(a).forEach(key => {
            if (a[key] !== b[key]){
                keys.push(key); 
                vals.push({
                    a: a[key],
                    b: b[key]
                });
            }
        }); 
        
        return [keys, vals]; 
    }
    
    var xiaoMing = {
        name: '小明',
        area: 'sz',
        school: '●0●',
        age: 11 
    }
    
    var xiaoHong = {
        name: '小红', 
        area: 'gz', 
        school: '(┬_┬)',
        age: 11 
    }
    
    var diffs = diffObj(xiaoMing, xiaoHong); 
    
    diffs[0].forEach((key, idx) => {
        console.group('Diff: ');
        console.log('key:', key, 'val:', diffs[1][idx]);
        console.groupEnd(); 
    })
    

    ScreenShot

    reply
    0
  • 欧阳克

    欧阳克2017-07-05 11:02:13

    Actually your question boils down to
    this question:

    function(value, key) {
        ret.push({key: value});
    }

    key will be parsed into a string "key", and the expectation is a variable key For example, when key="abc",value="123"
    the above actually becomes {"key":"123"} It should be {"abc":"123"}
    The most direct answer is var o = {}; o[key] = value; ret.push(o);
    But is there a simpler way? method?

    The following are the results of the discussion

    @240 var a={},b=a[key]=value,c=ret.push(a);
    @hotor var c;ret.push((c={},c[a]=b,c));
    @Gaubee ret.push(eval("({"+key+":\""+value+"\"})"));
    @hotor function(a,b,c){ret.push((c={},c[a]=b,c));}
    @240 ret[ret.push({})-1][key]=value;
    @Gaubee (ret[ret.length] = {})[key] = value;

    Note: The above answers are listed in chronological order. None of them have been fully tried. Please test carefully before using them. The main thing is to learn the ideas.
    As for which solution to choose, I hope to weigh it based on simplicity, performance and readability. Different people have different opinions

    This is a summary of a discussion in a QQ group. I am just a porter.

    reply
    0
  • typecho

    typecho2017-07-05 11:02:13

    ES6 supports object properties as variables, the writing method is:

    var a = 'x'
    var b = 'y'
    var obj = {
      [a]: 'this is x',
      [b]: 'this is y',
    }
    console.log(obj)

    In your push parameters, just use this writing method.

    reply
    0
  • Cancelreply