firestore iterator on querysnapshot [duplicate]

Существует несколько способов сделать то, что вы хотите. Чтобы добавить к уже сказанным @inalis и @Navi, вы можете использовать аргумент ключевого слова bbox_to_anchor, чтобы поместить легенду частично вне осей и / или уменьшить размер шрифта.

Прежде чем вы решите уменьшить размер шрифта (что может сильно усложнить чтение), попробуйте поиграть с размещением легенды в разных местах:

Итак, давайте начнем с общего Пример:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$' % i)

ax.legend()

plt.show()

alt text [/g2]

Если мы делаем то же самое, но используем аргумент ключевого слова bbox_to_anchor, мы можем смещать легенду немного за пределы осей границы:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$' % i)

ax.legend(bbox_to_anchor=(1.1, 1.05))

plt.show()

alt text [/g3]

Аналогичным образом вы можете сделать легенду более горизонтальной и / или поставить ее в верхней части рисунка (я также поворачивая закругленные углы и простую тень):

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    line, = ax.plot(x, i * x, label='$y = %ix$'%i)

ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.05),
          ncol=3, fancybox=True, shadow=True)
plt.show()

alt text [/g4]

Кроме того, вы можете уменьшить ширину текущего графика и поставить легенду полностью за пределами оси рисунка:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$'%i)

# Shrink current axis by 20%
box = ax.get_position()
ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])

# Put a legend to the right of the current axis
ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))

plt.show()

alt text [/g5]

И аналогичным образом вы можете сжать график по вертикали и поместить горизонтальный легенда внизу:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    line, = ax.plot(x, i * x, label='$y = %ix$'%i)

# Shrink current axis's height by 10% on the bottom
box = ax.get_position()
ax.set_position([box.x0, box.y0 + box.height * 0.1,
                 box.width, box.height * 0.9])

# Put a legend below current axis
ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.05),
          fancybox=True, shadow=True, ncol=5)

plt.show()

alt text [/g6]

Посмотрите на руководство по легенде matplotlib . Вы также можете взглянуть на plt.figlegend() . Надеюсь, что это поможет, во всяком случае!

2149
задан Evan Carroll 3 June 2016 в 01:27
поделиться

30 ответов

Вы можете использовать цикл for-in, как показано другими. Тем не менее, вы также должны убедиться, что ключ, который вы получаете, является фактическим свойством объекта и не исходит от прототипа.

Вот фрагмент:

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

for (var key in p) {
    if (p.hasOwnProperty(key)) {
        console.log(key + " -> " + p[key]);
    }
}

3486
ответ дан 1stthomas 20 August 2018 в 22:47
поделиться

Учитывая ES6, я хотел бы добавить свою собственную ложку сахара и предложить еще один подход к итерации по свойствам объекта.

Поскольку простой объект JS не является iterable просто вне поля, мы не можем использовать цикл for..of для итерации по его контенту. Но никто не может остановить нас, чтобы сделать его итерируемым.

Давайте будем иметь book объект.

let book = {
  title: "Amazing book",
  author: "Me",
  pages: 3
}

book[Symbol.iterator] = function(){

  let properties = Object.keys(this); // returns an array with property names
  let counter = 0;
  let isDone = false;

  let next = () => {
    if(counter >= properties.length){
      isDone = true;
    }
    return { done: isDone, value: this[properties[counter++]] }
  }

  return { next };
}

Поскольку мы сделали это, мы можем использовать его следующим образом:

for(let pValue of book){
  console.log(pValue);
}
------------------------
Amazing book
Me
3

Или, если вы знаете мощность генераторов ES6 , вы наверняка можете сделать код намного короче.

book[Symbol.iterator] = function *(){

  let properties = Object.keys(this);
  for (let p of properties){
    yield this[p];
  }

}

Конечно, вы может применять такое поведение для всех объектов, делая Object итерабельным на уровне prototype.

Object.prototype[Symbol.iterator] = function() {...}

Кроме того, объекты, которые соответствуют итерабельному протоколу, могут использоваться с новой функцией ES2015 spread , поэтому мы можем считывать значения свойств объекта в виде массива.

let pValues = [...book];
console.log(pValues);
-------------------------
["Amazing book", "Me", 3]

Или вы можете использовать назначение destructuring :

let [title, , pages] = book; // notice that we can just skip unnecessary values
console.log(title);
console.log(pages);
------------------
Amazing book
3

Вы можете проверить JSFiddle со всеми приведенными выше мной кодами.

3
ответ дан Artyom Pranovich 20 August 2018 в 22:47
поделиться

В соответствии с ECMAScript 5 вы можете комбинировать Object.keys() и Array.prototype.forEach() :

var obj = { first: "John", last: "Doe" };

Object.keys(obj).forEach(function(key) {
    console.log(key, obj[key]);
});

ES6 добавляет for...of :

for (const key of Object.keys(obj)) {
    console.log(key, obj[key]);
}

ES2017 добавляет Object.entries() , что позволяет не смотреть на каждое значение в исходном объекте:

Object.entries(obj).forEach(
    ([key, value]) => console.log(key, value)
);

Итерации Object.keys() и Object.entries() повторяются в том же порядке, что и петля for...in , но игнорируют цепочку прототипов . Исправлены только перечислимые свойства объекта.

Изменить: ES2016 → ES6

641
ответ дан Axel Rauschmayer 20 August 2018 в 22:47
поделиться

В ES6 у нас есть хорошо известные символы, чтобы разоблачить некоторые ранее внутренние методы, вы можете использовать его для определения того, как итераторы работают для этого объекта:

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3",
    *[Symbol.iterator]() {
        yield *Object.keys(this);
    }
};

[...p] //["p1", "p2", "p3"]

это даст тот же результат, что и для ... в цикле es6.

for(var key in p) {
    console.log(key);
}

Но важно знать, какие возможности у вас есть с помощью es6!

2
ответ дан Bamieh 20 August 2018 в 22:47
поделиться

Вы можете добавить к всем объектам простую функцию forEach , чтобы вы могли автоматически прокручивать любой объект:

Object.defineProperty(Object.prototype, 'forEach', {
    value: function (func) {
        for (var key in this) {
            if (!this.hasOwnProperty(key)) {
                // skip loop if the property is from prototype
                continue;
            }
            var value = this[key];
            func(key, value);
        }
    },
    enumerable: false
});

Для тех людей, которым не нравится " для ... в "- метод:

Object.defineProperty(Object.prototype, 'forEach', {
    value: function (func) {
        var arr = Object.keys(this);
        for (var i = 0; i < arr.length; i++) {
            var key = arr[i];
            func(key, this[key]);
        }
    },
    enumerable: false
});

Теперь вы можете просто позвонить:

p.forEach (function(key, value){
    console.log ("Key: " + key);
    console.log ("Value: " + value);
});

Если вы не хотите получить конфликты с другими forEach-методами, которые вы можете назвать им с вашим уникальным именем.

7
ответ дан Biber 20 August 2018 в 22:47
поделиться

через прототип с forEach (), который должен пропустить свойства цепи прототипа:

Object.prototype.each = function(f) {
    var obj = this
    Object.keys(obj).forEach( function(key) { 
        f( key , obj[key] ) 
    });
}


//print all keys and values
var obj = {a:1,b:2,c:3}
obj.each(function(key,value) { console.log(key + " " + value) });
// a 1
// b 2
// c 3
17
ответ дан bitstrider 20 August 2018 в 22:47
поделиться

Вы можете просто перебрать его, как:

for (var key in p) {
  alert(p[key]);
}

Обратите внимание, что key не будет принимать значение свойства, это просто значение индекса.

31
ответ дан Bryan 20 August 2018 в 22:47
поделиться

Объект становится итератором, когда он реализует метод .next ()

const james = {
name: 'James',
height: `5'10"`,
weight: 185,

[Symbol.iterator]() {
let properties = []
for (let key of Object.keys(james)){
     properties.push(key);
 }

index = 0;
return {
        next: () => {
            let key = properties[index];
            let value = this[key];
            let done = index >= properties.length - 1 ;
            index++;
            return { key, value, done };
        }
    };
  }

};


const iterator = james[Symbol.iterator]();

console.log(iterator.next().value); // 'James'
console.log(iterator.next().value); // `5'10`
console.log(iterator.next().value); // 185
2
ответ дан Dan Alboteanu 20 August 2018 в 22:47
поделиться

Если вы хотите итерации по неперечислимым свойствам , вы можете использовать Object.getOwnPropertyNames(obj) , чтобы вернуть массив всех свойств (перечислимых или нет), найденных напрямую на данном объекте.

var obj = Object.create({}, {
  // non-enumerable property
  getFoo: {
    value: function() { return this.foo; },
    enumerable: false
  }
});

obj.foo = 1; // enumerable property

Object.getOwnPropertyNames(obj).forEach(function (name) {
  document.write(name + ': ' + obj[name] + '<br/>');
});

3
ответ дан Dheeraj V.S. 20 August 2018 в 22:47
поделиться

Object.keys (obj): Array

извлекает все строкозначные ключи всех перечислимых собственных (не наследуемых) свойств.

So он дает тот же список ключей, что и вы, путем тестирования каждого ключа объекта с помощью hasOwnProperty. Вам не нужна эта дополнительная тестовая операция, чем и Object.keys( obj ).forEach(function( key ){}), как предполагается, быстрее. Докажем это:

var uniqid = function(){
			var text = "",
					i = 0,
					possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
			for( ; i < 32; i++ ) {
					text += possible.charAt( Math.floor( Math.random() * possible.length ) );
			}
			return text;
		}, 
		CYCLES = 100000,
		obj = {}, 
		p1,
		p2,
		p3,
		key;

// Populate object with random properties
Array.apply( null, Array( CYCLES ) ).forEach(function(){
	obj[ uniqid() ] = new Date()
});

// Approach #1
p1 = performance.now();
Object.keys( obj ).forEach(function( key ){
	var waste = obj[ key ];
});

p2 = performance.now();
console.log( "Object.keys approach took " + (p2 - p1) + " milliseconds.");

// Approach #2
for( key in obj ) {
	if ( obj.hasOwnProperty( key ) ) {
		var waste = obj[ key ];
	}
}

p3 = performance.now();
console.log( "for...in/hasOwnProperty approach took " + (p3 - p2) + " milliseconds.");

В моем Firefox у меня есть следующие результаты

  • Подход Object.keys 40.21101451665163 миллисекунд.
  • для подхода ... in / hasOwnProperty принято 98.26163508463651 миллисекунд.

PS. на Chrome разница еще больше http://codepen.io/dsheiko/pen/JdrqXa

PS2: В ES6 (EcmaScript 2015) вы можете повторить итерируемый объект более приятным:

let map = new Map().set('a', 1).set('b', 2);
for (let pair of map) {
    console.log(pair);
}

// OR 
let map = new Map([
    [false, 'no'],
    [true,  'yes'],
]);
map.forEach((value, key) => {
    console.log(key, value);
});

12
ответ дан Dmitry Sheiko 20 August 2018 в 22:47
поделиться

Поскольку es2015 становится все более популярным, я публикую этот ответ, который включает использование генератора и итератора для плавной перебора через пары [key, value]. Как это возможно в других языках, например Ruby.

Хорошо, вот код:

const MyObject = {
  'a': 'Hello',
  'b': 'it\'s',
  'c': 'me',
  'd': 'you',
  'e': 'looking',
  'f': 'for',
  [Symbol.iterator]: function* () {
    for (const i of Object.keys(this)) {
      yield [i, this[i]];
    }
  }
};

for (const [k, v] of MyObject) {
  console.log(`Here is key ${k} and here is value ${v}`);
}

Вся информация о том, как вы можете сделать итератор и генератор, который вы можете найти у разработчика Mozilla page.

Надеюсь, это помогло кому-то.

EDIT:

ES2017 будет включать в себя Object.entries, который сделает итерацию по парам [key, value] в объектах еще более Полегче. Теперь известно, что он будет частью стандарта в соответствии с информацией о статусе ts39 .

Я думаю, что пришло время обновить мой ответ, чтобы он стал еще более свежим чем сейчас.

const MyObject = {
  'a': 'Hello',
  'b': 'it\'s',
  'c': 'me',
  'd': 'you',
  'e': 'looking',
  'f': 'for',
};

for (const [k, v] of Object.entries(MyObject)) {
  console.log(`Here is key ${k} and here is value ${v}`);
}

Вы можете узнать больше об использовании на странице MDN

24
ответ дан FieryCod 20 August 2018 в 22:47
поделиться

После просмотра всех ответов здесь hasOwnProperty не требуется для моего собственного использования, потому что мой json-объект чист; нет смысла добавлять дополнительную обработку javascript. Это все, что я использую:

for (var key in p) {
    console.log(key + ' => ' + p[key]);
    // key is key
    // value is p[key]
}
14
ответ дан Francis Lewis 20 August 2018 в 22:47
поделиться

Метод Object.keys() возвращает массив собственных перечислимых свойств данного объекта. Подробнее о нем здесь

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

Object.keys(p).map((key)=> console.log(key + "->" + p[key]))

8
ответ дан George Bailey 20 August 2018 в 22:47
поделиться

Вот еще один метод для итерации объекта.

   var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};


Object.keys(p).forEach(key => { console.log(key, p[key]) })

8
ответ дан Harsh Patel 20 August 2018 в 22:47
поделиться

Интересно, что люди в этих ответах затронули как Object.keys(), так и for...of, но никогда не комбинировали их:

var map = {well:'hello', there:'!'};
for (let key of Object.keys(map))
    console.log(key + ':' + map[key]);

Вы не можете просто for...of Object, потому что это не итератор и for...index или .forEach() в Object.keys() являются уродливыми / неэффективными. Я рад, что большинство людей воздерживаются от for...in (с проверкой или без проверки .hasOwnProperty()), так как это тоже немного грязно, поэтому, кроме моего ответа выше, я здесь, чтобы сказать ...


Вы можете сделать обычные ассоциации объектов итерации! Поведение так же, как Map s с прямым использованием fancy for...of DEMO , работающего в Chrome и FF (я предполагаю только ES6)

var ordinaryObject = {well:'hello', there:'!'};
for (let pair of ordinaryObject)
    //key:value
    console.log(pair[0] + ':' + pair[1]);

//or
for (let [key, value] of ordinaryObject)
    console.log(key + ':' + value);

Пока вы включаете моя подкладка ниже:

//makes all objects iterable just like Maps!!! YAY
//iterates over Object.keys() (which already ignores prototype chain for us)
Object.prototype[Symbol.iterator] = function() {
    var keys = Object.keys(this)[Symbol.iterator]();
    var obj = this;
    var output;
    return {next:function() {
        if (!(output = keys.next()).done)
            output.value = [output.value, obj[output.value]];
        return output;
    }};
};

Без создания реального объекта карты, который не имеет приятного синтаксического сахара.

var trueMap = new Map([['well', 'hello'], ['there', '!']]);
for (let pair of trueMap)
    console.log(pair[0] + ':' + pair[1]);

На самом деле, с помощью этой прокладки, если вы все еще хотели воспользоваться другими функциональными возможностями карты (без их обкатки), но все же хотели использовать аккуратную нотацию объекта, поскольку теперь объекты теперь можно итерабельны, теперь вы можете просто сделать карту из нее!

//shown in demo
var realMap = new Map({well:'hello', there:'!'});
< hr>

Для тех, кто не любит подмешивать или вообще не вмешивается в prototype, не стесняйтесь делать эту функцию на окне, называя ее чем-то вроде getObjIterator(), тогда:

//no prototype manipulation
function getObjIterator(obj) {
    //create a dummy object instead of adding functionality to all objects
    var iterator = new Object();

    //give it what the shim does but as its own local property
    iterator[Symbol.iterator] = function() {
        var keys = Object.keys(obj)[Symbol.iterator]();
        var output;

        return {next:function() {
            if (!(output = keys.next()).done)
                output.value = [output.value, obj[output.value]];
            return output;
        }};
    };

    return iterator;
}

Теперь вы можете просто называть его обычной функцией, ничего больше не влияет

var realMap = new Map(getObjIterator({well:'hello', there:'!'}))

или

for (let pair of getObjIterator(ordinaryObject))

Нет причин, по которым это не было бы

Добро пожаловать в будущее.

14
ответ дан Hashbrown 20 August 2018 в 22:47
поделиться

У меня была аналогичная проблема при использовании Angular, вот решение, которое я нашел.

Шаг 1. Получите все ключи объектов. используя Object.keys. Этот метод возвращает массив собственных перечислимых свойств данного объекта.

Шаг 2. Создайте пустой массив. Это место, где все свойства будут жить, так как ваш новый цикл ngFor будет указывать на этот массив, мы должны поймать их всех. Шаг 3. Итеражируйте все ключи и нажимайте каждый в массив, который вы создали. Вот как это выглядит в коде.

    // Evil response in a variable. Here are all my vehicles.
let evilResponse = { 
  "car" : 
    { 
       "color" : "red",
       "model" : "2013"
    },
   "motorcycle": 
    { 
       "color" : "red",
       "model" : "2016"
    },
   "bicycle": 
    { 
       "color" : "red",
       "model" : "2011"
    }
}
// Step 1. Get all the object keys.
let evilResponseProps = Object.keys(evilResponse);
// Step 2. Create an empty array.
let goodResponse = [];
// Step 3. Iterate throw all keys.
for (prop of evilResponseProps) { 
    goodResponse.push(evilResponseProps[prop]);
}

Вот ссылка на исходный пост. https://medium.com/@papaponmx/looping-over-object-properties-with-ngfor-in-angular-869cd7b2ddcc

0
ответ дан Jaime Rios 20 August 2018 в 22:47
поделиться
for(key in p) {
  alert( p[key] );
}

Примечание: вы можете делать это по массивам, но вы будете перебирать и length и другие свойства.

14
ответ дан Kristian 20 August 2018 в 22:47
поделиться

Я сделал бы это вместо проверки obj.hasOwnerProperty в каждом цикле for ... in.

var obj = {a : 1};
for(var key in obj){
    //obj.hasOwnProperty(key) is not needed.
    console.log(key);
}
//then check if anybody has messed the native object. Put this code at the end of the page.
for(var key in Object){
    throw new Error("Please don't extend the native object");
}
4
ответ дан Lewis 20 August 2018 в 22:47
поделиться

Если вы хотите выполнять итерацию только по свойствам, используйте один из приведенных выше ответов, однако, если вы хотите перебрать все, включая функции, то вы можете использовать Object.getOwnPropertyNames (obj)

for (let o of Object.getOwnPropertyNames(Math)) {
  console.log(o);
}

Я иногда использую это для быстрого тестирования всех функций на объектах с простыми входами и выходами.

1
ответ дан Matas Vaitkevicius 20 August 2018 в 22:47
поделиться

Вопрос не будет полным, если мы не упомянем об альтернативных методах для обхода объектов.

В настоящее время многие известные библиотеки JavaScript предоставляют свои собственные методы для итерации над коллекциями, то есть над массивов , объектов и в виде массива . Эти методы удобны в использовании и полностью совместимы с любым браузером.

  1. Если вы работаете с jQuery, вы можете использовать метод jQuery.each() . Его можно использовать для беспрепятственной итерации по обоим объектам и массивам:
    $.each(obj, function(key, value) {
        console.log(key, value);
    });
    
  2. В Underscore.js вы можете найти метод _.each() , который выполняет итерацию по списку элементов, каждый из которых, в свою очередь, передается в заданную функцию (обратите внимание на порядок аргументов в функции iteratee !):
    _.each(obj, function(value, key) {
        console.log(key, value);
    });
    
  3. Lo-Dash предоставляет несколько методов для итерации поверх свойств объекта , Основной _.forEach() (или его псевдоним _.each()) полезен для циклического перемещения по обоим объектам и массивам, однако (!) Объекты с свойством length рассматриваются как массивы, и чтобы избежать такого поведения, предлагается использовать методы _.forIn() и _.forOwn() (они также имеют первый аргумент value):
    _.forIn(obj, function(value, key) {
        console.log(key, value);
    });
    
    _.forIn() выполняет итерацию по и унаследовал перечислимые свойства объекта, тогда как _.forOwn() выполняет итерацию только над собственными свойствами объекта (в основном проверяя функцию hasOwnProperty). Для простых объектов и литералов объектов любой из этих методов будет работать нормально.

Как правило, все описанные методы имеют одинаковое поведение с любыми поставленными объектами. Кроме того, использование нативного цикла for..in обычно будет быстрее , чем любая абстракция, например jQuery.each(), эти методы значительно проще в использовании, требуют меньше кодирования и обеспечивают лучшую обработку ошибок.

231
ответ дан meagar 20 August 2018 в 22:47
поделиться

Циклы могут быть довольно интересными при использовании чистого JavaScript. Похоже, что только ECMA6 (спецификация JavaScript для нового 2015 года) получил контроль над циклами. К сожалению, поскольку я пишу это, оба браузера и популярная интегрированная среда разработки (IDE) по-прежнему изо всех сил пытаются полностью поддержать новые колокола и свистки.

На первый взгляд, вот как выглядит цикл JavaScript JavaScript раньше ECMA6:

for (var key in object) {
  if (p.hasOwnProperty(key)) {
    var value = object[key];
    console.log(key); // This is the key;
    console.log(value); // This is the value;
  }
}

Кроме того, я знаю, что этот вопрос выходит за рамки этого вопроса, но в 2011 году ECMAScript 5.1 добавил метод forEach только для массивов, который в основном создал новый улучшенный способ циклического преобразования массивов в то же время оставляя неизменяемые объекты со старым многословным и запутанным циклом for. Но нечетная часть заключается в том, что этот новый метод forEach не поддерживает break, что привело к возникновению всех других проблем.

В основном в 2011 году не существует реального твердого метода для цикла в JavaScript чем то, что многие популярные библиотеки (jQuery, Underscore и т. д.) решили повторно реализовать.

С 2015 года у нас теперь есть лучший способ использовать цикл (и разбивать) любой тип объекта ( включая массивы и строки). Вот как выглядит цикл в JavaScript, когда рекомендация станет основной:

for (let [key, value] of Object.entries(object)) {
    console.log(key); // This is the key;
    console.log(value); // This is the value;
}

Обратите внимание, что большинство браузеров не будут поддерживать код выше с 18 июня 2016 года. Даже в Chrome вам нужно включите этот специальный флаг для работы: chrome://flags/#enable-javascript-harmony

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

5
ответ дан Nicolas Bouvrette 20 August 2018 в 22:47
поделиться

В ECMAScript 5 у вас есть новый подход в итерационных полях literal - Object.keys

. Дополнительную информацию вы можете увидеть на MDN

Мой выбор ниже, как более быстрое решение в текущих версиях браузеров (Chrome30, IE10, FF25)

var keys = Object.keys(p),
    len = keys.length,
    i = 0,
    prop,
    value;
while (i < len) {
    prop = keys[i];
    value = p[prop];
    i += 1;
}

Вы можете сравнить производительность этого подхода с различными реализациями на jsperf.com :

Поддержка браузера, которую вы можете видеть на таблице сопоставления Kangax

Для старого браузера у вас простой и full polyfill

UPD:

сравнение производительности для всех наиболее популярных случаев в этом вопросе на perfjs.info:

объектная итерация

47
ответ дан Pencroff 20 August 2018 в 22:47
поделиться

Только код JavaScript без зависимостей:

var p = {"p1": "value1", "p2": "value2", "p3": "value3"};
keys = Object.keys(p);   // ["p1", "p2", "p3"]

for(i = 0; i < keys.length; i++){
  console.log(keys[i] + "=" + p[keys[i]]);   // p1=value1, p2=value2, p3=value3
}
5
ответ дан Peter Mortensen 20 August 2018 в 22:47
поделиться

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

for (var key in p) {
    if (p.hasOwnProperty(key)) {
        console.log(key + " = " + p[key]);
    }
}
<p>
  Output:<br>
  p1 = values1<br>
  p2 = values2<br>
  p3 = values3
</p>

7
ответ дан RensvWalstijn 20 August 2018 в 22:47
поделиться
    var p =[{"username":"ordermanageadmin","user_id":"2","resource_id":"Magento_Sales::actions"},
{"username":"ordermanageadmin_1","user_id":"3","resource_id":"Magento_Sales::actions"}]
for(var value in p) {
    for (var key in value) {
        if (p.hasOwnProperty(key)) {
            console.log(key + " -> " + p[key]);
        }
    }
}
1
ответ дан senthil 20 August 2018 в 22:47
поделиться

Предисловие:

  • Свойства объекта могут быть own (свойство принадлежит самому объекту) или унаследовано (а не на объекте (один из его прототипов).
  • Свойства объекта могут быть перечислены или неперечислимыми . Неперечислимые свойства исключаются из множества перечислений свойств / массивов.
  • Имена свойств могут быть строками или символами. Свойства, имена которых являются символами, не учитываются в множестве перечислений свойств / массивов.

Здесь, в 2018 году, ваши возможности для прокрутки свойств объекта:

  1. for-in [ MDN , spec ] & mdash; Структура цикла, которая пересекает имена объектов перечисляемых свойств, включая унаследованные, имена которых являются строками
  2. Object.keys [ MDN , spec ] & mdash; Функция, предоставляющая массив имен свойств собственного , перечисляемых , имена которых являются строками.
  3. Object.values [ MDN , spec ] & mdash; Функция, предоставляющая массив значений свойств объекта , перечисляемых .
  4. Object.entries [ ] MDN , spec ] & mdash; Функция, предоставляющая массив значений имен и для свойств объекта , перечисляемых .
  5. Object.getOwnPropertyNames [ MDN , spec ] & mdash; Функция, предоставляющая массив имен свойств собственного объекта (даже неперечислимых), имена которых являются строками.
  6. Object.getOwnPropertySymbols [ MDN , spec ] & mdash; Функция, предоставляющая массив имен свойств собственного объекта объекта (даже неперечислимых), имена которых являются символами.
  7. Reflect.ownKeys [ MDN , spec ] & mdash; Функция, предоставляющая массив имен свойств собственного объекта объекта (даже неперечислимых), являются ли эти имена строками или символами.
  8. Если вы хотите, чтобы все объекты свойства, включая неперечислимые унаследованные, вам нужно использовать цикл и Object.getPrototypeOf [ MDN , spec ] и использовать Object.getOwnPropertyNames, Object.getOwnPropertySymbols или Reflect.ownKeys для каждого объекта в цепочке прототипов (пример внизу этого ответа).

Со всеми из них, кроме for-in, вы использовали бы какую-то петлевую конструкцию на (for, for-of, forEach и т. д.).

Примеры:

for-in:

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name in o) {
    const value = o[name];
    console.log(`${name} = ${value}`);
}

Object.keys (с контуром for-of, но вы можете использовать любую петлевую конструкцию) :

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name of Object.keys(o)) {
    const value = o[name];
    console.log(`${name} = ${value}`);
}

Object.values:

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const value of Object.values(o)) {
    console.log(`${value}`);
}

Object.entries:

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const [name, value] of Object.entries(o)) {
    console.log(`${name} = ${value}`);
}

Object.getOwnPropertyNames:

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name of Object.getOwnPropertyNames(o)) {
    const value = o[name];
    console.log(`${name} = ${value}`);
}

Object.getOwnPropertySymbols :

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name of Object.getOwnPropertySymbols(o)) {
    const value = o[name];
    console.log(`${String(name)} = ${value}`);
}

Reflect.ownKeys:

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name of Reflect.ownKeys(o)) {
    const value = o[name];
    console.log(`${String(name)} = ${value}`);
}

Все свойства, включая унаследованные неперечислимые:

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (let depth = 0, current = o; current; ++depth, current = Object.getPrototypeOf(current)) {
    for (const name of Reflect.ownKeys(current)) {
        const value = o[name];
        console.log(`[${depth}] ${String(name)} = ${String(value)}`);
    }
}
.as-console-wrapper {
  max-height: 100% !important;
}

10
ответ дан T.J. Crowder 20 August 2018 в 22:47
поделиться

Если кому-то нужно перебирать объекты массива с условием:

var arrayObjects = [{"building":"A", "status":"good"},{"building":"B","status":"horrible"}];

for (var i=0; i< arrayObjects.length; i++) {
  console.log(arrayObjects[i]);
  
  for(key in arrayObjects[i]) {      
    
      if (key == "status" && arrayObjects[i][key] == "good") {
        
          console.log(key + "->" + arrayObjects[i][key]);
      }else{
          console.log("nothing found");
      }
   }
}

2
ответ дан Tadas V. 20 August 2018 в 22:47
поделиться

Вы должны использовать цикл in-in

. Но будьте очень осторожны при использовании этого типа цикла, потому что это зациклирует все свойства вдоль цепи прототипа.

Поэтому , при использовании for-in циклов всегда используйте метод hasOwnProperty, чтобы определить, действительно ли текущее свойство в итерации является свойством объекта, который вы проверяете:

for (var prop in p) {
    if (!p.hasOwnProperty(prop)) {
        //The current property is not a direct property of p
        continue;
    }
    //Do your logic with the property here
}
300
ответ дан Vitim.us 20 August 2018 в 22:47
поделиться

, так как ES06 вы можете получить значения объекта как массива с

let arrValues = Object.values( yourObject) ;

, он возвращает массив значений объекта и не извлекает значения из Prototype !!

MDN DOCS Object.values ​​()

0
ответ дан yehonatan yehezkel 20 August 2018 в 22:47
поделиться
  • отступ одного уровня
  • одиночный набор скобок
  • максимальная совместимость с браузером
  • hasOwnProperty safe

var p = {"p1": "value1", "p2": "value2", "p3": "value3"};

for (var key in p) if (p.hasOwnProperty(key)) {
  var value = p[key];
  console.log(key, value);
}

-1
ответ дан Zectbumo 20 August 2018 в 22:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: