多个键名,相同的对值

时间:2013-02-07 04:25:48

标签: javascript

我正在尝试在具有多个名称的密钥的JavaScript脚本中设置对象文字。引用相同的对象值,即我已经尝试过的类似的东西:

var holidays: {
    "thanksgiving day", "thanksgiving", "t-day": {
        someValue : "foo"
    }
}

var holidays: {
    ["thanksgiving day", "thanksgiving", "t-day"]: {
        someValue : "foo"
    }
}

我有办法实现这个目标吗?

11 个答案:

答案 0 :(得分:8)

另一种方法是进行一些后处理

function expand(obj) {
    var keys = Object.keys(obj);
    for (var i = 0; i < keys.length; ++i) {
        var key = keys[i],
            subkeys = key.split(/,\s?/),
            target = obj[key];
        delete obj[key];
        subkeys.forEach(function(key) { obj[key] = target; })
    }
    return obj;
}

var holidays = expand({
    "thanksgiving day, thanksgiving, t-day": {
        someValue : "foo"
    } 
});

答案 1 :(得分:7)

JSON不提供这样的功能,也不提供Javascript对象文字。

你或许能够做到这样的事情:

holidays = {
    thanksgiving: {foo: 'foo'},
    groundhogDay: {foo: 'bar'},
    aliases: {
        'thanksgiving day': 'thanksgiving',
        't-day': 'thanksgiving',
        'Bill Murrays nightmare': 'groundhogDay'
    }
}

然后你可以检查

holidays[name] || holidays[holidays.aliases[name]]

您的数据。

这不是一个很好的解决方案。但是编写一个通过以下表示形式创建此类对象的小函数并不会太困难:

[
    {
        names: ['thanksgiving', 'thanksgiving day', 't-day'],
        obj: {foo: 'foo'}
    },
    {
        names: ['groundhogDay', 'Bill Murrays nightmare'],
        obj: {foo: 'bar'}
    },
]

如果这样更容易维护。

答案 2 :(得分:4)

另一种解决方案,如果你能负担RegExp执行,那么ES6代理:

let align = new Proxy({

    'start|top|left': -1,
    'middle|center': 0,
    'end|bottom|right': 1,

}, {

    get: function(target, property, receiver) {

        for (let k in target)
            if (new RegExp(k).test(property))
                return target[k]

        return null

    }

})

align.start     // -1
align.top       // -1
align.left      // -1

align.middle    // 0
align.center    // 0

align.end       // 1
align.bottom    // 1
align.right     // 1

见文档:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/get

答案 3 :(得分:3)

我想你可以这样做:

var holidays = {
  'thanksgiving day': {
    foo: 'foo'
  }
};

holidays.thanksgiving = holidays['t-day'] = holidays['thanksgiving day'];

如果你发现自己经常这样做,或者你有更多的价值观,请考虑这种模式:

'thanksgiving, t-day, thanks, thank, thank u'.split(',').forEach(function(key) {
  holidays[key] = holidays['thanksgiving day'];
});

更好的方法是事先处理您的数据,而不是添加重复数据。

答案 4 :(得分:2)

这应该按预期工作:

function getItem(_key) {
    items = [{
        item: 'a',
        keys: ['xyz','foo']
    },{
        item: 'b',
        keys: ['xwt','bar']
    }];

    _filtered = items.filter(function(item) {
        return item.keys.indexOf(_key) != -1
    }).map(function(item) {
        return item.item;
    });
    return !!_filtered.length ? _filtered[0] : false;
}

答案 5 :(得分:1)

相同的响应(ES6代理,RegExp),但是更短的方式(并且显着不太清晰)

let align = new Proxy({

    'start|top|left': -1,
    'middle|center': 0,
    'end|bottom|right': 1,

}, { get: (t, p) => Object.keys(t).reduce((r, v) => r !== undefined ? r : (new RegExp(v).test(p) ? t[v] : undefined), undefined) })

align.start     // -1
align.top       // -1
align.left      // -1

align.middle    // 0
align.center    // 0

align.end       // 1
align.bottom    // 1
align.right     // 1

答案 6 :(得分:0)

我遇到了这个问题,这就是我提出的问题

function objectDive(parent, str){
  if(typeof str === 'object'){
    if(str.length){
      var str0 = str.shift();
      return objectDive(parent[str0], str);
    }else{
      return parent;
    }
  }else{
    if(typeof str === 'string'){
      return objectDive(parent,str.split('.'));
    }
  }
}

答案 7 :(得分:0)

现在这对你来说可能有些过分,但这是一个通用函数,它将创建一个带有“多个键”的对象。它实际上做的是拥有一个具有实际值的不动产,然后定义getter和setter以将操作从虚拟键转发到实际属性。

SELECT 
   IDCol_1
  ,IDCol_2
  ,Count(*) Over(Partition By IDCol_1, IDCol_2 order by IDCol_1) as numDistinct
FROM Table_1

这不像你期望的那样粗略,一旦创建对象基本上没有性能损失,并且在枚举(function multiKey(keyGroups) { let obj = {}; let props = {}; for (let keyGroup of keyGroups) { let masterKey = keyGroup[0]; let prop = { configurable: true, enumerable: false, get() { return obj[masterKey]; }, set(value) { obj[masterKey] = value; } }; obj[masterKey] = undefined; for (let i = 1; i < keyGroup.length; ++i) { if (keyGroup.hasOwnProperty(i)) { props[keyGroup[i]] = prop; } } } return Object.defineProperties(obj, props); } 循环)和成员资格测试(for...in运算符)方面表现良好。以下是一些示例用法:

in

取自my Gist,你可以分叉。

答案 8 :(得分:0)

//create some objects(!) you want to have aliases for..like tags
var {learn,image,programming} = 
 ["learn", "image", "programming"].map(tag=>({toString:()=>tag }));


//create arbitrary many aliases using a Map
var alias = new Map();
alias.set("photo", image);
alias.set("pic", image);
alias.set("learning", learn);
alias.set("coding", programming);

//best put the original tagNames in here too.. 
//pretty easy huh? 

// returns the image object 
alias.get("pic");

// ;)

答案 9 :(得分:0)

使用ES6你可以这样做,但它并不理想:

const holidays = {
    "single": {
        singleValue: "foo",
    },

    ...([
        "thanksgiving day", "thanksgiving", "t-day",
    ].reduce((a, v) => ({...a, [v]: {
        someValue: "foo",
    }}), {})),

    "other": {
        otherValue: "foo",
    },
};

我仍然认为最干净的解决方案可能是:

let holidays = {
    "t-day": {
        someValue: "foo",
    },
};
holidays["thanksgiving"] = holidays["t-day"];
holidays["thanksgiving day"] = holidays["t-day"];

答案 10 :(得分:0)

这里有一种方法可以使用共享相同值的多个键来初始化对象

const API_PATH = https://librational-talker.000webhostapp.com/peopleBase/employee_informationAPI.php


 getUsersData = e => {
  e.preventDefault();
  axios({
    method: 'users',
    url: `${API_PATH}`,
    headers: { 'content-type': 'application/json' },
    data: this.state
  })
    .then(result => {
       this.setState({ loading: false, users: res.data });
    })
    .catch(error => this.setState({ error: error.message }));
};

虽然我个人觉得写出来会更清楚

相关问题