JavaScript - получить элемент массива, удовлетворяющий условию - PullRequest
31 голосов
/ 23 сентября 2010

Я изучаю JavaScript, используя W3C, и я не нашел ответа на этот вопрос.

Я пытаюсь сделать некоторые манипуляции с элементами массива, которые удовлетворяют некоторому условию.

Есть ли способ сделать это, кроме запуска на элементах массива в цикле for?Может быть что-то вроде (на других языках):

foreach (object t in tArray)
   if (t follows some condition...) t++;

другое дело, иногда я хочу использовать значение элемента, а иногда я хочу использовать его как ссылку.в чем синтаксическая разница?

Также я буду рад рекомендациям по более обширным сайтам для изучения JavaScript.спасибо

Ответы [ 8 ]

30 голосов
/ 23 сентября 2010

В большинстве браузеров (не IE <= 8) массивы имеют метод <a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/filter" rel="noreferrer">filter, который не делает то, что вам нужно, но создает массив элементов исходного массива, которые удовлетворяют определенное условие:

function isGreaterThanFive(x) {
     return x > 5;
}

[1, 10, 4, 6].filter(isGreaterThanFive); // Returns [10, 6]

Сеть разработчиков Mozilla имеет много хороших ресурсов JavaScript.

7 голосов
/ 15 ноября 2018

Используйте ES6 Array.filter() и функции стрелок с телом выражения:

myArray.filter(x => x > 5)

Немного более лаконично, чем ответ @ Beauty.

6 голосов
/ 10 мая 2017

Здесь короткий путь для написания фильтра.Из массива чисел он возвращает все значения больше 5.

myArray.filter((x) => { return x > 5; })

Пример использования:

var filterResult = [1, 10, 4, 6].filter((x) => { return x > 5; });
console.log(filterResult); // returns [ 10, 6 ]

А вот фильтр для массива объектов ,который проверяет свойство условие.

myArray.filter((x) => { return x.myNumber > 5; })

Пример использования:

var myArray = [{myNumber: 1, name: 'one'}, {myNumber: 3, name: 'tree'}, {myNumber: 6, name: 'six'}, {myNumber: 8, name: 'eight'}];
var result = myArray.filter((x) => { return x.myNumber > 5; });
console.log(result); // returns [ { myNumber: 6, name: 'six' }, { myNumber: 8, name: 'eight' } ]
3 голосов
/ 23 сентября 2010

Вы можете использовать for ... in в JavaScript:

for (var key in array) {
    if (/* some condition */) {
        // ...
    }
}

Начиная с JavaScript 1.6, вы также можете использовать это:

for each (var element in array) {
    // ...
}

Они в основном предназначены для обхода свойств объекта,Вам следует просто использовать for -loop.

EDIT: Вы можете использовать JavaScript-фреймворк, такой как jQuery , чтобы устранить эти кросс-браузерные проблемы.Попробуйте.Его $.each() -метод выполняет свою работу.

1 голос
/ 22 мая 2018

Вы можете использовать Array.prototype.find , который делает именно то, что вы хотите, возвращает первый элемент, удовлетворяющий условию. Пример:

> ([4, {a:7}, 7, {a:5, k:'r'}, 8]).find(o => o.a == 5)

{a:5, k:'r'}
1 голос
/ 23 сентября 2010

О массивах

Для итерации по массиву обычно требуется метод forEach :

arr.forEach(function(el) {
  alert(el);
});

В вашем конкретном случае дляувеличивая каждый элемент массива, я бы порекомендовал метод map :

arr = arr.map(function(t){ return t+1; });

Есть также фильтр , Reduction и другие, что тоже пригодится.

Но, как уже упоминал Тим Даун, в IE они не будут работать по умолчанию.Но вы также можете легко добавить эти методы для IE, как показано в документации по MDC, или вы даже можете написать более простые версии, чем те, которые описаны в документации по MDC (я не знаю, почему они так не поддерживают JavaScript):

if (!Array.prototype.forEach) {
  Array.prototype.forEach = function(func, scope) {
    for (var i = 0, len = this.length; i < len; i++) {
      func.call(scope, this[i], i, this);
    }
  };
}

Но не используйте конструкцию for ... in для массивов - она ​​предназначена для объектов.

Об ссылках

Другое дело, иногда я хочу использовать значение элемента, а иногда я хочу использовать его как ссылку.В чем синтаксическая разница?

В JavaScript каждая переменная фактически является ссылкой на некоторый объект.Но эти ссылки передаются по значению.Позвольте мне объяснить ...

Вы можете передать объект в функцию, которая изменяет объект, и изменения будут видны вне функции:

function incrementHeight(person) {
  person.height = person.height + 1;
}
var p = {height: 10);
alert(p.height); // outputs: 10
incrementHeight(p);
alert(p.height); // outputs: 11

Здесь вы изменяете значение, к которомуссылка person указывает на и поэтому изменение будет отражено вне функции.

Но что-то вроде этого не получается:

function incrementHeight(height) {
  height = height + 1;
}
var h = 10;
alert(h); // outputs: 10
incrementHeight(h);
alert(h); // outputs: 10

Здесь вы создаете совершенно новый объект 11 иназначьте его ссылку на переменную height.Но переменная h вне функции по-прежнему содержит старую ссылку и поэтому остается указывать на 10.

0 голосов
/ 15 июня 2018

Напишите обобщенную функцию, которая принимает различные условия :

function array_only(arr, condition) {
    hold_test=[]
    arr.map(function(e, i) {if(eval(condition)){hold_test.push(e)}})
    return(hold_test)
    }

Пример:

use_array = ['hello', 'go_there', 'now', 'go_here', 'hello.png', 'gogo.log', 'hoho.png']

Использование :

return только элементы, содержащие .log расширение:

array_only(use_array, "e.includes('.log')")

['gogo.log']

return только элементы, содержащие .png расширение:

array_only(use_array, "e.includes('.png')")

['hello.png', 'hoho.png']

возврат * только 1032 *элементы НЕ содержат .png расширение:

array_only(use_array, "!e.includes('.png')")

['hello', 'go_there', 'now', 'go_here', 'gogo.log']

возврат элементов, содержащих набор расширений и префиксов:

array_only(use_array, "['go_', '.png', '.log'].some(el => e.includes(el))")

['go_there', 'go_here', 'hello.png',' gogo.log ',' hoho.png ']

Вы можете легко передать НЕСКОЛЬКО УСЛОВИЙ

вернуть все файлы png, которые являютсядлиной менее 9 символов:

array_only(use_array, "e.includes('.png') && e.length<9")

['hoho.png']

0 голосов
/ 28 июля 2016

Просто наткнулся на ту же проблему. Тим Даун подошел ближе, ему просто нужна была оболочка для длины отфильтрованного массива:

// count elements fulfilling a condition
Array.prototype.count = function (f) {
  return this.filter(f).length;  
};

Использование:

// get the answer weight from the question's values array
var w = Math.pow(q.values.count(function(v) { return v !== -1; }), -1);

Я надеюсь, что это ответ на этот давний вопрос!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...