首頁  >  問答  >  主體

javascript - 如何將變數做為一個物件的key,push進一個陣列?

a,b 的key都是相等的

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

或是有什麼更好,更效率,更屌的辦法嗎?

我要達到的效果是這樣的

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

這個問題的根本就是,在宣告一個物件時,如何把變數當作一個key。

世界只因有你世界只因有你2663 天前1499

全部回覆(4)我來回復

  • PHP中文网

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

    ES6 允許字面量定義物件時,以表達式作為物件的屬性名稱

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

    回覆
    0
  • 淡淡烟草味

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

    修改了問題描述之後的答案

    這個問題的根本就是,在宣告一個物件時,如何把變數當作一個key

    如果變數是字串或數字

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

    如果變數是物件

    那就要用 ES6 的 Map 了

    看程式碼 很容易理解,是上一個方法的超集

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

    ScreenShot


    新的寫法

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

    利用 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


    修改之前

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

    實作

    額。 。看了老久問題描述 也不是很清楚你要做什麼

    姑且根據函數名稱和 before after 這些來猜,你是想要把 a 物件 和 b 物件不同的屬性和值分別放進 before 和 after 嗎? 如果是 可以看看下面程式碼

    
    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

    回覆
    0
  • 欧阳克

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

    其實你的問題可歸結為
    這樣的問題:

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

    key會被解析成字串"key",期望是變數key 例當key="abc",value="123"
    上述實際變成{"key":"123"} 應該是{"abc":"123"}
    最直接的答案是var o = {}; o[key] = value; ret.push(o);
    但是有沒有更簡潔的簡潔的簡潔方法?

    以下是討論結果

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

    註:以上答案是按時間先後順序列出,均沒有完整試過,大家使用前請謹慎測試,主要是要學習到其中的思想。
    對於具體選用哪個解法 希望根據 簡潔 性能和 可讀性去權衡 仁者見仁

    是在一個QQ群組裡討論的總結,我只是搬運工。

    回覆
    0
  • typecho

    typecho2017-07-05 11:02:13

    ES6支援物件屬性為變量,的寫法:

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

    在你的push參數中,使用這種寫法就可以了。

    回覆
    0
  • 取消回覆