2014-04-11 20 views
31

tôi có một đối tượng JSON cực lớn có cấu trúc như thế này:chính Swap với giá trị JSON

{A : 1, B : 2, C : 3, D : 4} 

Tôi cần một chức năng có thể trao đổi các giá trị với các phím trong đối tượng của tôi và tôi không biết làm thế nào để làm điều đó . Tôi sẽ cần một đầu ra như thế này:

{1 : A, 2 : B, 3 : C, 4 : D} 

Có cách nào mà tôi có thể làm điều này bằng tay sẽ tạo ra một đối tượng mới, nơi mọi thứ được hoán đổi?
Cảm ơn

+1

là tất cả các số giá trị và các con số có lặp lại không? Nếu các giá trị lặp lại thì bạn sẽ không thể hoán đổi chúng vì chúng sẽ ghi đè lên các giá trị khác, trừ khi bạn thay đổi giá trị của chúng thành một giá trị duy nhất. Có thể có giải pháp tốt hơn lý do cần trao đổi là gì? –

+0

@PatrickEvans Chúng đều là số nhưng chúng không lặp lại. Tôi đang cố gắng tạo một mật mã cơ bản. – C1D

Trả lời

45
function swap(json){ 
    var ret = {}; 
    for(var key in json){ 
    ret[json[key]] = key; 
    } 
    return ret; 
} 

Ví dụ ở đây FIDDLE đừng quên để bật giao diện điều khiển của bạn để xem kết quả.

+0

Cảm ơn bạn rất nhiều vì điều này! Tôi đã tìm kiếm trên tất cả các stackexchange và không thể tìm thấy một câu trả lời. – C1D

+0

Bạn được chào đón :) – jPO

+1

vẻ đẹp của điều này là làm việc cho 'javascript' là tốt.+ 1vote – AXL

21

Lấy các khóa của đối tượng, sau đó sử dụng chức năng giảm của Array để đi qua từng khóa và đặt giá trị làm khóa và khóa làm giá trị.

var data = {A : 1, B : 2, C : 3, D : 4} 
var newData = Object.keys(data).reduce(function(obj,key){ 
    obj[ data[key] ] = key; 
    return obj; 
},{}); 
console.log(newData); 
15

bạn có thể sử dụng chức năng lodash _.invert nó cũng có thể sử dụng multivlaue

var object = { 'a': 1, 'b': 2, 'c': 1 }; 

    _.invert(object); 
    // => { '1': 'c', '2': 'b' } 

    // with `multiValue` 
    _.invert(object, true); 
    // => { '1': ['a', 'c'], '2': ['b'] } 
11

Trong ES6/ES2015 bạn có thể kết hợp sử dụng các Object.keysreduce với Object.assign chức năng mới, một arrow function, và một computed property name cho một giải pháp tuyên bố đơn giản đơn giản.

const foo = { a: 1, b: 2, c: 3 }; 
const bar = Object.keys(foo) 
    .reduce((obj, key) => Object.assign({}, obj, { [foo[key]]: key }), {}); 

Nếu bạn đang sử dụng transpiling object spread operator (giai đoạn 3 như các văn bản này) sẽ đơn giản hóa mọi thứ một chút nữa.

const foo = { a: 1, b: 2, c: 3 }; 
const bar = Object.keys(foo) 
    .reduce((obj, key) => ({ ...obj, [foo[key]]: key }), {}); 

Cuối cùng, nếu bạn có Object.entries sẵn (giai đoạn 4 như các văn bản), bạn có thể dọn dẹp logic một liên lạc hơn (IMO).

const foo = { a: 1, b: 2, c: 3 }; 
const bar = Object.entries(foo) 
    .reduce((obj, [key, value]) => ({ ...obj, [value]: key }), {}); 
+0

Cú phápError: /Users/markus/Entwicklung/IT1_Beleg/public/es6/vokabeltrainer.js: Mã thông báo không mong muốn (53:45) 51 | if (btoa) { 52 | entries = Object.entries (mục) > 53 | .reduce ((obj, [key, value]) => ({... obj, [giá trị]: khóa}), {}); |^ – Superlokkus

+0

@Superlokkus cách giải thích tốt nhất của tôi về đầu ra lỗi đó là bạn không chuyển đổi cú pháp lây lan đối tượng, và tính đến hôm nay, tôi không biết bất kỳ công cụ JavaScript nào hỗ trợ nó nguyên bản. – joslarson

3

Sử dụng ES6:

const obj = { a: "aaa", b: "bbb", c: "ccc", d: "ddd" }; 
Object.assign({}, ...Object.entries(obj).map(([a,b]) => ({ [b]: a }))) 
1

Sử dụng Ramda:

const swapKeysWithValues = (source) => 
    R.pipe(
    R.keys, 
    R.reduce((obj, k) => R.assoc(source[k], k, obj), {}) 
)(source); 
0

Như một sự bổ sung của @joslarson và @jPO câu trả lời:
Without ES6 cần thiết, bạn có thể sử dụng Object.keysArray.reduce và số Comma Operator:

Object.keys(foo).reduce((obj, key) => (obj[foo[key]] = key, obj), {}); 

Một số có thể thấy nó xấu xí, nhưng nó "nhanh hơn" khi reduce không phát tán tất cả các thuộc tính của obj trên mỗi vòng lặp.

Các vấn đề liên quan