Loại bỏ thuộc tính cho tất cả các đối tượng trong mảng


108

Tôi muốn xóa thuộc badtính khỏi mọi đối tượng trong mảng. Có cách nào tốt hơn để làm điều đó ngoài việc sử dụng một forvòng lặp và xóa nó khỏi mọi đối tượng không?

var array = [{"bad": "something", "good":"something"},{"bad":"something", "good":"something"},...];

for (var i = 0, len = array.length; i < len; i++) {
  delete array[i].bad;
}

Có vẻ như cần phải có một cách để sử dụng prototype, hoặc một cái gì đó. Tôi không biết. Ý tưởng?


1
Không quan trọng, các cách khác không thể nhận được O (n) tuyến tính ít hơn. Bất cứ điều gì bạn sử dụng, sẽ yêu cầu truy cập tất cả các phần tử mảng của bạn
Brian

Nguyên mẫu? Điều đó sẽ giúp ích như thế nào? Hay tất cả những đối tượng đó là các cá thể của cùng một hàm tạo và chia sẻ một giá trị chung bad?
Bergi

1
@Bergi Tôi tự hỏi liệu họ đang đề cập đến nguyên ArraymẫuJS hay nguyên mẫu, mà dystroy đã lấy làm ví dụ
Ian

Tôi không chắc bạn nên lưu trữ array.length trong một biến trước khi lặp. Tôi chắc rằng bạn sẽ thấy nó không đáng để bạn phải chịu đựng.
Denys Séguret

1
@ZackArgyle Có, trong trường hợp chung, không có gì nhanh hơn.
Denys Séguret

Câu trả lời:


118

Các cách khác duy nhất là thẩm mỹ và trên thực tế là các vòng lặp.

Ví dụ :

array.forEach(function(v){ delete v.bad });

Ghi chú:

  • nếu bạn muốn tương thích với IE8, bạn cần một miếng đệm cho forEach . Như bạn đề cập đến nguyên mẫu, prototype.js cũng có một miếng đệm .
  • deletelà một trong những "kẻ giết người tối ưu hóa" tồi tệ nhất . Sử dụng nó thường xuyên làm hỏng hiệu suất của các ứng dụng của bạn. Bạn không thể tránh nó nếu bạn thực sự muốn loại bỏ một thuộc tính nhưng bạn thường có thể đặt thuộc tính thành undefinedhoặc chỉ xây dựng các đối tượng mới mà không có thuộc tính.

1
Không tốt hơn so với các vòng lặp nhiều nếu vòng lặp được phép là "giả" -one lót quá: Pfor(var i = 0; i < array.length ) delete array[i].bad
Esailija

1
@Esailija Tùy. Tôi thích sử dụng forEachvì tôi thấy mã biểu cảm hơn (và vì tôi đã ngừng lo lắng về IE từ lâu).
Denys Séguret

1
Không ai trong số họ diễn đạt "xóa thuộc tính xấu của tất cả các đối tượng trong mảng này" theo cách hoàn toàn khác. forEachtự nó chung chung và vô nghĩa về mặt ngữ nghĩa, giống như một forvòng lặp.
Esailija

1
@Esailija Tôi đồng ý. Đó là lý do tại sao tôi chuẩn bị cho nó là "mỹ phẩm". Nó không rõ ràng trong câu trả lời của tôi?
Denys Séguret

Thật không may. Tôi sẽ gắn bó với vòng lặp for thường nhanh hơn forEach. Và thực sự ... ai quan tâm đến IE8. Cảm ơn đã giúp đỡ.
Zack Argyle

171

Với ES6, bạn có thể giải cấu trúc từng đối tượng để tạo đối tượng mới mà không có thuộc tính được đặt tên:

const newArray = array.map(({dropAttr1, dropAttr2, ...keepAttrs}) => keepAttrs)

16
Áp dụng cho vấn đề ban đầu nó có thể làconst newArray = array.map(({ bad, ...item }) => item);
dhilt

1
Đây là rất khuyến khích vì nó không sửa đổi các mảng ban đầu (hoạt động không thay đổi)
Pizzicato

1
Đây phải là câu trả lời được chấp nhận vì nó trả về một mảng mới, thay vì ghi đè lên mảng hiện có.
user1275105

câu trả lời tuyệt vời nhưng không làm việc nếu tên thuộc tính chứa dấu chấm ví dụ như 'bad.prop' (.)
Yayati

@Amiraslan tôi muốn sử dụng// eslint-disable-next-line no-unused-vars
piotr_cz

20

Tôi thích sử dụng bản đồ để xóa thuộc tính và sau đó trả lại mục mảng mới.

array.map(function(item) { 
    delete item.bad; 
    return item; 
});

12
Hãy nhận biết rằng đây đột biến ban đầu mảng
piotr_cz

1
Trong trường hợp này rõ ràng returntuyên bố sẽ không được yêu cầu
Sandeep Kumar

4
array.forEach(v => delete v.bad);
Anthony Awuley

14

Nếu bạn sử dụng underscore.js :

var strippedRows = _.map(rows, function (row) {
    return _.omit(row, ['bad', 'anotherbad']);
});

9

Giải pháp sử dụng nguyên mẫu chỉ khả thi khi các đối tượng của bạn giống nhau:

function Cons(g) { this.good = g; }
Cons.prototype.bad = "something common";
var array = [new Cons("something 1"), new Cons("something 2"), …];

Nhưng sau đó nó đơn giản (và O(1)):

delete Cons.prototype.bad;

3

Đối với ý kiến ​​của tôi, đây là biến thể đơn giản nhất

array.map(({good}) => ({good}))

3
câu hỏi là về việc loại bỏ cái xấu, không giữ cái tốt. Nếu các đối tượng của bạn có 10 trường cần giữ lại và một trường cần xóa, thì các trường trên sẽ thực sự dài để nhập.
adrien

1

Bạn có thể làm theo điều này, dễ đọc hơn, không phải tăng kỳ vọng do không tìm thấy khóa:

data.map((datum)=>{
                    return {
                        'id':datum.id,
                        'title':datum.login,
                    }

0

Tôi sẽ đề xuất sử dụng Object.assigntrong forEach()vòng lặp để các đối tượng được sao chép và không ảnh hưởng đến mảng đối tượng ban đầu

var res = [];
array.forEach(function(item) { 
    var tempItem = Object.assign({}, item);
    delete tempItem.bad; 
    res.push(tempItem);
});
console.log(res);

0

Câu hỏi này bây giờ hơi cũ, nhưng tôi muốn đưa ra một giải pháp thay thế không làm thay đổi dữ liệu nguồn và yêu cầu nỗ lực thủ công tối thiểu:

function mapOut(sourceObject, removeKeys = []) {
  const sourceKeys = Object.keys(sourceObject);
  const returnKeys = sourceKeys.filter(k => !removeKeys.includes(k));
  let returnObject = {};
  returnKeys.forEach(k => {
    returnObject[k] = sourceObject[k];
  });
  return returnObject;
}

const array = [
  {"bad": "something", "good":"something"},
  {"bad":"something", "good":"something"},
];

const newArray = array.map(obj => mapOut(obj, [ "bad", ]));

Nó vẫn chưa hoàn hảo một chút, nhưng duy trì một số mức độ bất biến và có thể linh hoạt đặt tên cho nhiều thuộc tính mà bạn muốn xóa. (Đề xuất được hoan nghênh)


0

tôi đã thử xóa một đối tượng mới mà không xóa coulmns trong Vue.js.

let data =this.selectedContactsDto[];

// đối tượng selectContactsDto [] = với danh sách các đối tượng mảng được tạo trong dự án của tôi

console.log (dữ liệu); let newDataObj = data.map (({groupsList, customFields, firstname, ... item}) => item); console.log ("newDataObj", newDataObj);


0

Để loại bỏ một số mảng đối tượng dạng cặp giá trị khóa, hãy sử dụng Postgres SQL làm cơ sở dữ liệu như ví dụ sau:

Đây là hàm người dùng trả về đối tượng chi tiết người dùng, chúng ta phải xóa khóa "api_secret" khỏi các hàng:

    function getCurrentUser(req, res, next) { // user function
    var userId = res.locals.userId;
    console.log(userId)
    db.runSQLWithParams("select * from users where id = $1", [userId], function(err, rows) {
      if(err){
        console.log(err)
      }
      var responseObject = {
        _embedded: rows,
      }
      responseObject._embedded[0].api_secret = undefined
      // console.log(api);
      // console.log(responseObject);
      res.json(responseObject);
    }); 
}

Hàm trên trả về đối tượng bên dưới dưới dạng phản hồi JSON trước đó

 {
    "_embedded": [
        {
            "id": "0123abd-345gfhgjf-dajd4456kkdj",
            "secret_key: "secret",
            "email": "abcd@email.com",
            "created": "2020-08-18T00:13:16.077Z"
        }
    ]
}

Sau khi thêm dòng này, responseObject._embedded[0].api_secret = undefinednó cho kết quả bên dưới là phản hồi JSON:

{
        "_embedded": [
            {
                "id": "0123abd-345gfhgjf-dajd4456kkdj",
                "email": "abcd@email.com",
                "created": "2020-08-18T00:13:16.077Z"
            }
        ]
    }

-4

var array = [{"bad": "something", "good":"something"},{"bad":"something", "good":"something"}];
var results = array.map(function(item){
  return {good : item["good"]}
});
console.log(JSON.stringify(results));


Bạn có thể giải thích giải pháp của bạn?
sg7

Bản đồ là một cấu trúc dữ liệu mới trong JavaScript ES6. Liên kết đính kèm có thể giúp bạn. hackernoon.com/what-you-should-know-about-es6-maps-dc66af6b9a1e
hk_y

giải pháp này không tốt nếu bạn có nhiều đạo cụ trong các mục của mình.
Koop4

Đúng! Cố gắng cung cấp một cách tiếp cận khác.
hk_y
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.