tìm chỉ số mảng của một đối tượng có giá trị khóa cụ thể trong dấu gạch dưới


91

Trong dấu gạch dưới, tôi có thể tìm thấy thành công một mặt hàng có giá trị khóa cụ thể

var tv = [{id:1},{id:2}]
var voteID = 2;
var data = _.find(tv, function(voteItem){ return voteItem.id == voteID; });
//data = { id: 2 }

nhưng làm cách nào để tìm chỉ mục mảng mà đối tượng đó đã xảy ra?



Cảm ơn - điều này rất hữu ích - nhưng trong ví dụ được liệt kê, bạn đang tìm kiếm một số duy nhất trong một mảng số - tôi đang tìm kiếm một giá trị khóa trong một mảng đối tượng. Chức năng này sẽ đáp ứng điều đó?
mheavers

2
Cho dù nó là một bài kiểm tra số hay vị từ thuộc tính công bằng của bạn không quan trọng, vâng.
Bergi

Hãy thử findIndex:var dataIndex = _.findIndex(tv, { id: voteID })
Tom Söderlund

Vui lòng xem xét chấp nhận câu trả lời đưa ra giải pháp cho Dấu gạch dưới , như được yêu cầu trong câu hỏi.
Nigel B. Peck

Câu trả lời:


28

Tôi không biết liệu có phương pháp gạch dưới hiện tại nào thực hiện điều này hay không, nhưng bạn có thể đạt được kết quả tương tự với javascript thuần túy.

Array.prototype.getIndexBy = function (name, value) {
    for (var i = 0; i < this.length; i++) {
        if (this[i][name] == value) {
            return i;
        }
    }
    return -1;
}

Sau đó, bạn chỉ có thể làm:

var data = tv[tv.getIndexBy("id", 2)]


4
Tại sao không phải là một return -1;theo mặc định?
Radu Chiriac

171

findIndex đã được thêm vào trong 1.8:

index = _.findIndex(tv, function(voteItem) { return voteItem.id == voteID })

Xem: http://underscorejs.org/#findIndex

Ngoài ra, điều này cũng hoạt động, nếu bạn không ngại tạo một danh sách tạm thời khác:

index = _.indexOf(_.pluck(tv, 'id'), voteId);

Xem: http://underscorejs.org/#pluck


Tôi không chắc chắn về gạch nhưng trong lodash bạn không cần một chức năng ẩn danh, chỉ đơn giản là index = _.findIndex(tv, {id: voteID})sẽ làm việc, cũng hoạt động nếu tvbộ sưu tập đã phức tạp hơn giá trị (nhiều hơn chỉ là một idtài sản)
Scott Jungwirth

1
Chỉ cần một điểm sử dụng gảy là rất chậm hơn nhiều. Tôi vì nó đi ngang thêm. jsperf.com/compare-find-index
Farshid Saberi

38

Nếu bạn muốn duy trì dấu gạch dưới để chức năng vị ngữ của bạn có thể linh hoạt hơn, đây là 2 ý tưởng.

Phương pháp 1

Vì vị từ for _.findnhận cả giá trị và chỉ mục của một phần tử, bạn có thể sử dụng hiệu ứng phụ để truy xuất chỉ mục, như sau:

var idx;
_.find(tv, function(voteItem, voteIdx){ 
   if(voteItem.id == voteID){ idx = voteIdx; return true;}; 
});

Phương pháp 2

Nhìn vào nguồn gạch dưới, đây là cách _.findđược triển khai:

_.find = _.detect = function(obj, predicate, context) {
  var result;
  any(obj, function(value, index, list) {
    if (predicate.call(context, value, index, list)) {
      result = value;
      return true;
    }
  });
  return result;
};

Để biến đây thành một findIndexhàm, chỉ cần thay thế dòng result = value;bằng result = index;Đây là ý tưởng giống như phương pháp đầu tiên. Tôi bao gồm nó để chỉ ra rằng gạch dưới cũng sử dụng tác dụng phụ để triển khai _.find.


37

Lo-Dash , mở rộng Dấu gạch dưới, có phương thức findIndex , có thể tìm chỉ mục của một đối tượng nhất định, hoặc theo một vị từ nhất định hoặc theo các thuộc tính của một đối tượng nhất định.

Trong trường hợp của bạn, tôi sẽ làm:

var index = _.findIndex(tv, { id: voteID });

Hãy thử một lần.


findIntex nó là một phương pháp từ dấu gạch ngang, không phải từ dấu gạch dưới
Wallysson Nunes

4
@WallyssonNunes Đây là chính xác những gì tôi đã viết - "Lo-Dash, kéo dài gạch, có phương pháp findIndex"
splintor

3
Đây hiện là một phần của thư viện gạch tiêu chuẩn, như các phiên bản 1.8.0: underscorejs.org/#1.8.0
Gage Trader

10

Nếu môi trường đích của bạn hỗ trợ ES2015 (hoặc bạn có một bước chuyển tiếp, ví dụ như với Babel), bạn có thể sử dụng Array.prototype.findIndex ().

Cho ví dụ của bạn

const array = [ {id:1}, {id:2} ]
const desiredId = 2;
const index = array.findIndex(obj => obj.id === desiredId);

4

bạn có thể sử dụng indexOfphương pháp từlodash

var tv = [{id:1},{id:2}]
var voteID = 2;
var data = _.find(tv, function(voteItem){ return voteItem.id == voteID; });
var index=_.indexOf(tv,data);

3

Giữ nó đơn giản:

// Find the index of the first element in array
// meeting specified condition.
//
var findIndex = function(arr, cond) {
  var i, x;
  for (i in arr) {
    x = arr[i];
    if (cond(x)) return parseInt(i);
  }
};

var idIsTwo = function(x) { return x.id == 2 }
var tv = [ {id: 1}, {id: 2} ]
var i = findIndex(tv, idIsTwo) // 1

Hoặc, đối với những người không ghét, biến thể CoffeeScript:

findIndex = (arr, cond) ->
  for i, x of arr
    return parseInt(i) if cond(x)

1
tốt hơn sẽ làreturn parseInt(i) for i, x of array when cond(x)
maregar

1
Làm thế nào điều này là đơn giản hơn các câu trả lời trước đây ??
ncubica

2

Điều này là để giúp lodashngười dùng. kiểm tra xem chìa khóa của bạn có hiện diện hay không bằng cách thực hiện:

hideSelectedCompany(yourKey) {
 return _.findIndex(yourArray, n => n === yourKey) === -1;
}

1

Giải pháp đơn giản nhất là sử dụng lodash:

  1. Cài đặt lodash:

npm install - lưu lodash

  1. Sử dụng phương thức findIndex:

const _ = request ('lodash');

findIndexByElementKeyValue = (elementKeyValue) => {
  return _.findIndex(array, arrayItem => arrayItem.keyelementKeyValue);
}

0

Nếu bạn đang mong đợi nhiều kết quả phù hợp và do đó cần một mảng được trả về, hãy thử:

_.where(Users, {age: 24})

Nếu giá trị thuộc tính là duy nhất và bạn cần chỉ mục của đối sánh, hãy thử:

_.findWhere(Users, {_id: 10})

0
Array.prototype.getIndex = function (obj) {
    for (var i = 0; i < this.length; i++) {
        if (this[i][Id] == obj.Id) {
            return i;
        }
    }
    return -1;
}

List.getIndex(obj);

0

Tôi gặp trường hợp tương tự nhưng ngược lại là tìm khóa đã sử dụng dựa trên chỉ mục của một đối tượng nhất định. Tôi có thể tìm thấy giải pháp trong dấu gạch dưới bằng cách sử dụng Object.valuesđể trả về đối tượng trong một mảng để lấy chỉ mục xảy ra.

var tv = {id1:1,id2:2};
var voteIndex = 1;
console.log(_.findKey(tv, function(item) {
  return _.indexOf(Object.values(tv), item) == voteIndex;
}));
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>

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.