Làm cách nào để có một tập hợp con các thuộc tính của đối tượng javascript


425

Nói rằng tôi có một đối tượng:

elmo = { 
  color: 'red',
  annoying: true,
  height: 'unknown',
  meta: { one: '1', two: '2'}
};

Tôi muốn tạo một đối tượng mới với một tập hợp các thuộc tính của nó.

 // pseudo code
 subset = elmo.slice('color', 'height')

 //=> { color: 'red', height: 'unknown' }

Làm thế nào tôi có thể đạt được điều này?


2
Thư viện Underscore có rất nhiều chức năng của trình trợ giúp như thế này, hãy kiểm tra xem: underscorejs.org/#pick
Stefan

4
Tôi nghĩ rằng emo.slicethoạt nhìn.
Bill Criswell

1
Suy nghĩ thứ hai ... Tôi sẽ không tạo ra một tập hợp con ...
Andrew

Câu trả lời:


674

Sử dụng cấu trúc đối tượng và tốc ký tài sản

const object = { a: 5, b: 6, c: 7  };
const picked = (({ a, c }) => ({ a, c }))(object);

console.log(picked); // { a: 5, c: 7 }


Từ Philipp Kewisch:

Đây thực sự chỉ là một chức năng ẩn danh được gọi ngay lập tức. Tất cả những điều này có thể được tìm thấy trên trang Phân công hủy cấu trúc trên MDN. Đây là một hình thức mở rộng

let unwrap = ({a, c}) => ({a, c});

let unwrap2 = function({a, c}) { return { a, c }; };

let picked = unwrap({ a: 5, b: 6, c: 7 });

let picked2 = unwrap2({a: 5, b: 6, c: 7})

console.log(picked)
console.log(picked2)


37
Làm thế nào bạn tìm hiểu về cách làm điều này? Không ở đâu trong bất kỳ tài liệu hoặc bài viết nào tôi thấy (bao gồm MDN), nó hiển thị cú pháp mũi tên đang được sử dụng trong Cấu trúc đối tượng. Điều này là rất tốt đẹp để biết.
papiro

52
Đây thực sự chỉ là một chức năng ẩn danh được gọi ngay lập tức. Tất cả những điều này có thể được tìm thấy trên trang Phân công hủy cấu trúc trên MDN. Đây là một hình thức mở rộng: let unwrap = ({a, c}) => ({a, c}); let unwrap2 = function({a, c}) { return { a, c }; }; let picked = unwrap({ a: 5, b: 6, c: 7 });
Philipp Kewisch

8
Có cách nào để làm điều đó một cách linh hoạt với toán tử lây lan không?
Tom Sarduy

4
@TomSarduy bạn có thể sử dụng phần còn lại nếu bạn muốn chỉ định loại đạo cụ nào cần xóa, ví dụ: const { b, ...picked } = objectsẽ tạo pickednhư { a: 5, c: 7 }. Bạn đã chỉ định đơn giản để loại bỏ b. Mặc dù vậy, eslint của bạn có thể sẽ gây khó chịu cho bạn vì đã khai báo một var mà bạn không sử dụng.
Josh từ Qaribou

24
Một bất lợi ở đây là bạn cần phải gõ đầy đủ chuỗi tên thuộc tính hai lần. Đó có thể là một vấn đề trong trường hợp cần chọn nhiều thuộc tính.
Gershom

144

Tôi đề nghị hãy xem Lodash ; Nó có rất nhiều chức năng tiện ích tuyệt vời.

Ví dụ pick()sẽ là chính xác những gì bạn tìm kiếm:

var subset = _.pick(elmo, ['color', 'height']);

vĩ cầm


2
tương tự cho underscore.js
Dan

1
Có chức năng nào để chỉ loại trừ các trường nhất định thay vì chọn không? vì vậy tôi có khoảng 50 trường trong json của mình và muốn mọi thứ trừ 2 trường.
Shrikant Bohhu

7
Vâng! bạn có thể sử dụng _.omit(elmo, ['voice'])để trả lại mọi thứ nhưngvoice
xavdid

Điều tôi không thích về cách tiếp cận này là bạn đặt tên trường trong ngoặc kép để dễ bị lỗi chính tả, các phép tái cấu trúc phổ biến như đổi tên một thuộc tính trong IDE của bạn sẽ không nhận nó, v.v.
Andy

117

Nếu bạn đang sử dụng ES6, có một cách rất ngắn gọn để thực hiện việc này bằng cách sử dụng hàm hủy. Phá hủy cấu trúc cho phép bạn dễ dàng thêm vào các đối tượng bằng cách sử dụng một trải, nhưng nó cũng cho phép bạn tạo các đối tượng tập hợp con theo cùng một cách.

const object = {
  a: 'a',
  b: 'b',
  c: 'c',
  d: 'd',
}

// Remove "c" and "d" fields from original object:
const {c, d, ...partialObject} = object;
const subset = {c, d};

console.log(partialObject) // => { a: 'a', b: 'b'}
console.log(subset) // => { c: 'c', d: 'd'};

6
Điều này chỉ hoạt động để loại bỏ một trường, không phải để chọn một tập hợp con đã biết? có khả năng vô số trường không xác định để xóa, nhưng đó có thể là điều mà một số người đang tìm kiếm
Alexander Mills

Đúng, nhưng nó có thể loại bỏ một số trường đã biết mà sau đó có thể được gán lại cho một đối tượng mới để nó vẫn cảm thấy có liên quan đến câu hỏi này. Thêm vào câu trả lời để minh họa thêm.
Lauren

1
Điều này về cơ bản giống như câu trả lời của @Ivan Nosov , mặc dù nó được giải thích theo cách dễ hiểu hơn ở đây
icc97

81

Mặc dù dài dòng hơn một chút, bạn có thể thực hiện những gì mọi người khác đã đề xuất gạch dưới / lodash trong 2 năm trước, bằng cách sử dụng Array.prototype.reduce .

var subset = ['color', 'height'].reduce(function(o, k) { o[k] = elmo[k]; return o; }, {});

Cách tiếp cận này giải quyết nó từ phía bên kia: thay vì lấy một đối tượng và chuyển tên thuộc tính cho nó để trích xuất, lấy một mảng tên thuộc tính và giảm chúng thành một đối tượng mới.

Mặc dù đơn giản hơn trong trường hợp đơn giản nhất, một cuộc gọi lại ở đây khá tiện lợi, vì bạn có thể dễ dàng đáp ứng một số yêu cầu chung, ví dụ: thay đổi thuộc tính 'màu' thành 'màu' trên đối tượng mới, làm phẳng các mảng, v.v. những việc bạn cần làm khi nhận một đối tượng từ một dịch vụ / thư viện và xây dựng một đối tượng mới cần ở một nơi khác. Mặc dù gạch dưới / lodash là các lib tuyệt vời, được triển khai tốt, đây là cách tiếp cận ưa thích của tôi để ít phụ thuộc vào nhà cung cấp hơn và cách tiếp cận đơn giản hơn, nhất quán hơn khi logic xây dựng tập hợp con của tôi trở nên phức tạp hơn.

chỉnh sửa: phiên bản es7 giống nhau:

const subset = ['color', 'height'].reduce((a, e) => (a[e] = elmo[e], a), {});

chỉnh sửa: Một ví dụ đẹp cho cà ri, quá! Có chức năng 'chọn' trả về chức năng khác.

const pick = (...props) => o => props.reduce((a, e) => ({ ...a, [e]: o[e] }), {});

Phương pháp trên khá gần với phương pháp khác, ngoại trừ nó cho phép bạn xây dựng một 'công cụ chọn' một cách nhanh chóng. ví dụ

pick('color', 'height')(elmo);

Điều đặc biệt gọn gàng về phương pháp này là bạn có thể dễ dàng chuyển các 'lựa chọn' vào bất cứ thứ gì có chức năng, ví dụ Array#map:

[elmo, grover, bigBird].map(pick('color', 'height'));
// [
//   { color: 'red', height: 'short' },
//   { color: 'blue', height: 'medium' },
//   { color: 'yellow', height: 'tall' },
// ]

3
es6 làm cho nó có thể sạch hơn thông qua các hàm mũi tên và trả về của Object.assign (vì việc gán cho một thuộc tính đối tượng trả về giá trị thuộc tính, nhưng Object.assign trả về đối tượng.)
Josh từ Qaribou

Một lưu ý khác về es6: bạn sẽ hiếm khi cần phải làm điều này nữa, vì bạn thường chỉ hủy cấu trúc bài tập hoặc đối số. ví dụ function showToy({ color, height }) {sẽ chỉ đặt những gì bạn cần trong phạm vi. Cách reducetiếp cận chủ yếu có ý nghĩa khi bạn đơn giản hóa các đối tượng để tuần tự hóa.
Josh từ Qaribou

6
Phiên bản ES6 đó ít hiệu suất hơn, bởi vì nó tạo một bản sao của tất cả các thuộc tính với mỗi lần lặp. Nó làm cho một hoạt động O (n) thành O (n ^ 2). Một ES6 tương đương với khối mã đầu tiên của bạn sẽ làconst pick = (obj, props) => props.reduce((a, e) => (a[e] = obj[e], a), {});
4castle

@ 4castle yep cuộc gọi tốt - không có ý nghĩa lặp đi lặp lại nhiều như vậy. Tôi thích cú pháp dấu phẩy - tốt hơn một loạt các trả về.
Josh từ Qaribou

1
@ShevchenkoViktor Tôi thực sự đã sử dụng cách tiếp cận đó trong phiên bản es6 ban đầu của mình, nhưng đã thay đổi nó sau nhận xét của @ 4castle. Tôi nghĩ rằng sự lây lan rõ ràng hơn, nhưng đó là một sự khác biệt lớn đối với các đối tượng lớn hơn trong mã có thể dễ dàng bị nghẽn cổ chai (ví dụ như trì hoãn dữ liệu kết xuất được trả về từ đó fetch), vì vậy tôi khuyên bạn nên thêm một nhận xét giải thích việc sử dụng toán tử dấu phẩy.
Josh từ Qaribou

45

Phá hủy ES6

Cú pháp phá hủy cho phép cấu trúc lại và kết hợp lại một đối tượng, với các tham số hàm hoặc biến.

Hạn chế là một danh sách các khóa được xác định trước, chúng không thể được liệt kê dưới dạng chuỗi, như câu hỏi đề cập. Việc phá hủy trở nên phức tạp hơn nếu một khóa không phải là chữ và số, ví dụ foo_bar.

Nhược điểm là điều này đòi hỏi phải sao chép danh sách các khóa, điều này dẫn đến mã dài dòng trong trường hợp danh sách dài. Vì việc hủy bỏ trùng lặp cú pháp đối tượng theo nghĩa đen trong trường hợp này, một danh sách có thể được sao chép và dán như vậy.

Ưu điểm là giải pháp hiệu quả của ES6 là tự nhiên.

IIFE

let subset = (({ foo, bar }) => ({ foo, bar }))(obj); // dupe ({ foo, bar })

Biến tạm thời

let { foo, bar } = obj;
let subset = { foo, bar }; // dupe { foo, bar }

Một danh sách các chuỗi

Danh sách các phím được chọn tùy ý bao gồm các chuỗi, như câu hỏi yêu cầu. Điều này cho phép không xác định trước chúng và sử dụng các biến có chứa tên chính, như pick(obj, 'foo', someKey, ...moreKeys).

Một lớp lót trở nên ngắn hơn với mỗi phiên bản JS.

ES5

var subset = Object.keys(obj)
.filter(function (key) { 
  return ['foo', 'bar'].indexOf(key) >= 0;
})
.reduce(function (obj2, key) {
  obj2[key] = obj[key];
  return obj2;
}, {});

ES6

let subset = Object.keys(obj)
.filter(key => ['foo', 'bar'].indexOf(key) >= 0)
.reduce((obj2, key) => Object.assign(obj2, { [key]: obj[key] }), {});

Hoặc với toán tử dấu phẩy:

let subset = Object.keys(obj)
.filter(key => ['foo', 'bar'].indexOf(key) >= 0)
.reduce((obj2, key) => (obj2[key] = obj[key], obj2), {});

ES2019

ECMAScript 2017 có Object.entriesArray.prototype.includes, ECMAScript 2019 có Object.fromEntries, chúng có thể được điền đầy đủ khi cần và giúp công việc dễ dàng hơn:

let subset = Object.fromEntries(
  Object.entries(obj)
  .filter(([key]) => ['foo', 'bar'].includes(key))
)

Một lớp lót có thể được viết lại dưới dạng hàm trợ giúp tương tự như Lodashpick hoặc omitnơi danh sách các khóa được truyền qua các đối số:

let pick = (obj, ...keys) => Object.fromEntries(
  Object.entries(obj)
  .filter(([key]) => keys.includes(key))
);

let subset = pick({ foo: 1, qux: 2 }, 'foo', 'bar'); // { foo: 1 }

Một lưu ý về các phím bị thiếu

Sự khác biệt chính giữa pickchức năng phá hủy và chức năng giống như thông thường là phá hủy bao gồm các khóa được chọn không tồn tại với undefinedgiá trị trong một tập hợp con:

(({ foo, bar }) => ({ foo, bar }))({ foo: 1 }) // { foo: 1, bar: undefined }

Hành vi này có thể hoặc không được mong muốn. Nó không thể được thay đổi để phá hủy cú pháp.

Trong khi pickcó thể thay đổi để bao gồm các phím bị thiếu bằng cách lặp lại danh sách các phím được chọn thay thế:

let inclusivePick = (obj, ...keys) => Object.fromEntries(
  keys.map(key => [key, obj[key]])
);

let subset = inclusivePick({ foo: 1, qux: 2 }, 'foo', 'bar'); // { foo: 1, bar: undefined }

11
Thật xấu hổ khi câu trả lời này rất gần đây và do đó không nhận được sự tiếp xúc mà nó xứng đáng. IMO nó phải là câu trả lời được chấp nhận cho sự hoàn chỉnh, đơn giản, linh hoạt và, chỉ cần làm việc. Tôi sẽ giữ phiên bản ES6 trong thư viện đoạn trích hữu ích nhất của mình.
VanAlbert

ES5 - "Uncaught ReferenceError: obj không được xác định"
Nikhil Vartak

@NikhilVartak Dự kiến objbiến đó là biến lưu trữ một đối tượng. Nếu tên biến của bạn khác, sử dụng nó thay vì obj.
Bình Estus

Lỗi của tôi! Tôi bỏ qua Object.keys(obj). Ngái ngủ.
Nikhil Vartak

34

Không có gì giống như được tích hợp vào thư viện lõi, nhưng bạn có thể sử dụng việc phá hủy đối tượng để làm điều đó ...

const {color, height} = sourceObject;
const newObject = {color, height};

Bạn cũng có thể viết một hàm tiện ích để làm điều đó ...

const cloneAndPluck = function(sourceObject, keys) {
    const newObject = {};
    keys.forEach((obj, key) => { newObject[key] = sourceObject[key]; });
    return newObject;
};

const subset = cloneAndPluck(elmo, ["color", "height"]);

Các thư viện như Lodash cũng có _.pick().


1
thật tuyệt, tôi chỉ phải thay đổi forEach thành: Keys.forEach (key => {newObject [key] = sourceObject [key];});. Xin vui lòng, cập nhật các bình luận nếu điều này có ý nghĩa.
kandan

34

Tôi đang thêm câu trả lời này vì không có câu trả lời nào được sử dụng Comma operator.

Nó rất dễ dàng với destructuring assignment,điều hành

const object = { a: 5, b: 6, c: 7  };
const picked = ({a,c} = object, {a,c})

console.log(picked);

Với một sự tăng cường nhất định cho việc gán thuộc tính động, nó có thể trông như thế này:


2
xấu của tôi, tôi không biết những gì tôi đã làm trước đó mà nó không hoạt động nhưng nó dường như hoạt động
ekkis

1
Đó là biểu hiện tốt nhất, khi nói đến sự hủy diệt
Mohamed Allal

1
giải pháp này rất thông minh, nhưng nó không hoạt động ở chế độ nghiêm ngặt (nghĩa là 'use strict'). Tôi nhận được một ReferenceError: a is not defined.
kimbaudi

8
Lưu ý rằng phương pháp này gây ô nhiễm phạm vi hiện tại với hai biến ac- cẩn thận không ghi đè ngẫu nhiên các vars cục bộ hoặc toàn cầu tùy thuộc vào ngữ cảnh. (Câu trả lời được chấp nhận sẽ tránh được vấn đề này bằng cách sử dụng hai biến cục bộ trong hàm nội tuyến, nằm ngoài phạm vi sau khi thực hiện ngay lập tức.)
mindplay.dk

2
Ô nhiễm không gian tên làm cho điều này hoàn toàn không thực tế. Điều cực kỳ phổ biến là đã có các biến trong phạm vi khớp với các thuộc tính của đối tượng, đó là lý do tại sao tốc độ prop + phá hủy tồn tại. Rất có thể bạn sẽ có chiều cao hoặc màu sắc đã được xác định như trong ví dụ ban đầu.
Josh từ Qaribou

23

Thêm một giải pháp:

var subset = {
   color: elmo.color,
   height: elmo.height 
}

Điều này có vẻ dễ đọc đối với tôi hơn bất kỳ câu trả lời nào cho đến nay, nhưng có lẽ đó chỉ là tôi!


9
Tôi thích làm việc hiệu quả hơn là mã ưa thích nhưng khó hiểu và trong công nghệ phần mềm thực tế, đây là giải pháp dễ đọc và dễ bảo trì nhất.
Janos

1
Có, tuy nhiên, với tôi, một mặt trái của việc sử dụng ký hiệu hủy diệt và tốc ký là nó ít bị lỗi hơn. Nếu tôi có một xu cho mỗi lần tôi sao chép nhầm và dán mã để kết thúc subset = {color: elmo.color, height: elmo.color}, thì tôi đã có ít nhất một ... ừm, có lẽ là một xu.
JHH

Tôi sẽ không gọi tốc ký hủy diệt dễ bị lỗi hơn vì nó không phải là DRY
gman

Tôi phải đồng ý. Không gây ô nhiễm bối cảnh với các biến không mong muốn, đây là giải pháp dễ đọc nhất. Phần còn lại nhìn quá khó hiểu. Tôi thích hiểu mã của tôi lần thứ hai tôi nhìn vào nó.
Andrew

11

Bạn cũng có thể sử dụng Lodash .

var subset = _.pick(elmo ,'color', 'height');

Bổ sung, giả sử bạn có một mảng "elmo":

elmos = [{ 
      color: 'red',
      annoying: true,
      height: 'unknown',
      meta: { one: '1', two: '2'}
    },{ 
      color: 'blue',
      annoying: true,
      height: 'known',
      meta: { one: '1', two: '2'}
    },{ 
      color: 'yellow',
      annoying: false,
      height: 'unknown',
      meta: { one: '1', two: '2'}
    }
];

Nếu bạn muốn hành vi tương tự, sử dụng lodash, bạn sẽ chỉ:

var subsets = _.map(elmos, function(elm) { return _.pick(elm, 'color', 'height'); });

10

Việc cấu trúc thành các biến được đặt tên động là không thể trong JavaScript như được thảo luận trong câu hỏi này .

Để thiết lập các khóa động , bạn có thể sử dụng chức năng giảm mà không làm biến đổi đối tượng như sau:

const getSubset = (obj, ...keys) => keys.reduce((a, c) => ({ ...a, [c]: obj[c] }), {});

const elmo = { 
  color: 'red',
  annoying: true,
  height: 'unknown',
  meta: { one: '1', two: '2'}
}

const subset = getSubset(elmo, 'color', 'annoying')
console.log(subset)

Nên lưu ý rằng bạn đang tạo một đối tượng mới trên mỗi lần lặp thay vì cập nhật một bản sao duy nhất. - mpen

bên dưới là phiên bản sử dụng giảm với bản sao duy nhất (cập nhật giá trị ban đầu được truyền vào để giảm).

const getSubset = (obj, ...keys) => keys.reduce((acc, curr) => {
  acc[curr] = obj[curr]
  return acc
}, {})

const elmo = { 
  color: 'red',
  annoying: true,
  height: 'unknown',
  meta: { one: '1', two: '2'}
}

const subset = getSubset(elmo, 'annoying', 'height', 'meta')
console.log(subset)


1
Tuyệt vời! Nó đã khiến tôi mất một lúc không nhận ra các dấu ngoặc quan trọng như thế nào trên [c] :. Tôi cho rằng bằng cách nào đó khiến c được xem như một giá trị thay vì tên của tài sản. Dù sao, rất mát mẻ. +1
John Fairbanks

Cảm ơn bạn đời! Cách sử dụng đó là một điều tôi thích về JavaScript, cho phép các hàm chung mà không cần sử dụng eval. Đơn giản, những gì nó tạo ra là cho phép bạn đặt một khóa dict thành một biến khi chạy. nếu bạn xác định var key = 'someKey', thì bạn có thể sử dụng nó dưới dạng {[key]: 'value'}, cung cấp cho bạn {someKey: 'value'}. Thật tuyệt
Muhammet Enginar

1
Nên lưu ý rằng bạn đang tạo một đối tượng mới trên mỗi lần lặp thay vì cập nhật một bản sao duy nhất.
mở

1
@mpen tìm tốt. Tôi đã thêm một phiên bản đột biến một bản sao duy nhất khi bạn đề xuất cũng trải rộng các đối số thay vì chuyển một loạt các khóa.
Muhammet Enginar

7

Giải pháp TypeScript:

export function pick<T extends object, U extends keyof T>(obj: T, paths: Array<U>) {
    return paths.reduce((o, k) => {
        o[k] = obj[k];
        return o;
    }, Object.create(null));
}

Thông tin gõ thậm chí cho phép tự động hoàn thành:

Tín dụng cho DefiniteTyped cho U extends keyof Tlừa!


Không làm việc cho tôi.
Nuthinking

@Nuthinking Bạn đang sử dụng Mã VS?
mở

vâng, tôi sử dụng mã VS.
Nuthinking

@Nuthinking Và bạn đặt nó trong một tập tin .ts? Cần làm việc. Tôi vừa thử lại lần nữa
mpen


4

Giải pháp động

['color', 'height'].reduce((a,b) => (a[b]=elmo[b],a), {})


3

Chỉ là một cách khác ...

var elmo = { 
  color: 'red',
  annoying: true,
  height: 'unknown',
  meta: { one: '1', two: '2'}
}

var subset = [elmo].map(x => ({
  color: x.color,
  height: x.height
}))[0]

Bạn có thể sử dụng hàm này với một mảng các Đối tượng =)


2

Làm thế nào về:

function sliceObj(obj) {
  var o = {}
    , keys = [].slice.call(arguments, 1);
  for (var i=0; i<keys.length; i++) {
    if (keys[i] in obj) o[keys[i]] = obj[keys[i]];
  }
  return o;
}

var subset = sliceObj(elmo, 'color', 'height');

Điều này sẽ thất bại nếu giá trị của tài sản là false(hoặc giả). jsfiddle.net/nfAs8
Alxandr

Đó là lý do tại sao tôi đổi nó thành keys[i] in obj.
elclanrs

2

Điều này hoạt động với tôi trong bảng điều khiển Chrome. Bất kỳ vấn đề với điều này?

var { color, height } = elmo
var subelmo = { color, height }
console.log(subelmo) // {color: "red", height: "unknown"}

4
Điều này đọc tốt, nhưng tạo ra hai biến không cần thiết, màu sắc và chiều cao.
dùng424174

Không hiểu bình luận của bạn. Yêu cầu của OP là tạo ra một đối tượng có hai yếu tố đó
MSi

@MSi Điều này không chỉ tạo một đối tượng, nó cũng tạo ra hai biến.
Thiết kế bởi Adrian

1

Phân công cơ cấu với các thuộc tính động

Giải pháp này không chỉ áp dụng cho ví dụ cụ thể của bạn mà còn áp dụng chung hơn:

const subset2 = (x, y) => ({[x]:a, [y]:b}) => ({[x]:a, [y]:b});

const subset3 = (x, y, z) => ({[x]:a, [y]:b, [z]:c}) => ({[x]:a, [y]:b, [z]:c});

// const subset4...etc.


const o = {a:1, b:2, c:3, d:4, e:5};


const pickBD = subset2("b", "d");
const pickACE = subset3("a", "c", "e");


console.log(
  pickBD(o), // {b:2, d:4}
  pickACE(o) // {a:1, c:3, e:5}
);

Bạn có thể dễ dàng xác định subset4vv để đưa nhiều tài sản vào tài khoản.


1

Tốt tuổi Array.prototype.reduce:

const selectable = {a: null, b: null};
const v = {a: true, b: 'yes', c: 4};

const r = Object.keys(selectable).reduce((a, b) => {
  return (a[b] = v[b]), a;
}, {});

console.log(r);

câu trả lời này sử dụng toán tử dấu phẩy ma thuật, cũng: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator

Nếu bạn muốn thực sự ưa thích, cái này nhỏ gọn hơn:

const r = Object.keys(selectable).reduce((a, b) => (a[b] = v[b], a), {});

Đặt tất cả lại với nhau thành một chức năng có thể tái sử dụng:

const getSelectable = function (selectable, original) {
  return Object.keys(selectable).reduce((a, b) => (a[b] = original[b], a), {})
};

const r = getSelectable(selectable, v);
console.log(r);

1
  1. chuyển đổi đối số thành mảng

  2. sử dụng Array.forEach()để chọn tài sản

    Object.prototype.pick = function(...args) {
       var obj = {};
       args.forEach(k => obj[k] = this[k])
       return obj
    }
    var a = {0:"a",1:"b",2:"c"}
    var b = a.pick('1','2')  //output will be {1: "b", 2: "c"}

4
Mở rộng nguyên mẫu của các kiểu bản địa được coi là thực hành xấu, mặc dù nó sẽ hoạt động. Đừng làm điều này nếu bạn đang viết một thư viện.
Emile Bergeron

0
function splice()
{
    var ret = new Object();

    for(i = 1; i < arguments.length; i++)
        ret[arguments[i]] = arguments[0][arguments[i]];

    return ret;
}

var answer = splice(elmo, "color", "height");

0

Thử

const elmo={color:"red",annoying:!0,height:"unknown",meta:{one:"1",two:"2"}};

const {color, height} = elmo; newObject = ({color, height});

console.log(newObject); //{ color: 'red', height: 'unknown' }

0

Thêm 2 xu của tôi vào câu trả lời của Ivan Nosov :

Trong trường hợp của tôi, tôi cần nhiều phím để được "cắt" ra khỏi vật thể để nó trở nên xấu xí rất nhanh và không phải là một giải pháp rất năng động:

const object = { a: 5, b: 6, c: 7, d: 8, aa: 5, bb: 6, cc: 7, dd: 8, aaa: 5, bbb: 6, ccc: 7, ddd: 8, ab: 5, bc: 6, cd: 7, de: 8  };
const picked = (({ a, aa, aaa, ab, c, cc, ccc, cd }) => ({ a, aa, aaa, ab, c, cc, ccc, cd }))(object);

console.log(picked);

Vì vậy, đây là một giải pháp năng động bằng cách sử dụng eval:

const slice = (k, o) => eval(`(${k} => ${k})(o)`);


const object    = { a: 5, b: 6, c: 7, d: 8, aa: 5, bb: 6, cc: 7, dd: 8, aaa: 5, bbb: 6, ccc: 7, ddd: 8, ab: 5, bc: 6, cd: 7, de: 8  };
const sliceKeys = '({ a, aa, aaa, ab, c, cc, ccc, cd })';

console.log( slice(sliceKeys, object) );

-2

Lưu ý: mặc dù câu hỏi ban đầu được hỏi là dành cho javascript, nhưng nó có thể được thực hiện jQuery bằng giải pháp bên dưới

bạn có thể mở rộng jquery nếu bạn muốn đây là mã mẫu cho một lát:

jQuery.extend({
  sliceMe: function(obj, str) {
      var returnJsonObj = null;
    $.each( obj, function(name, value){
        alert("name: "+name+", value: "+value);
        if(name==str){
            returnJsonObj = JSON.stringify("{"+name+":"+value+"}");
        }

    });
      return returnJsonObj;
  }
});

var elmo = { 
  color: 'red',
  annoying: true,
  height: 'unknown',
  meta: { one: '1', two: '2'}
};


var temp = $.sliceMe(elmo,"color");
alert(JSON.stringify(temp));

đây là câu đố cho cùng: http://jsfiddle.net/w633z/


16
Jquery là gì?
Christian Schlensker

1
@ChristianSchlensker là javascript
Kevin B
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.