У меня есть массив, созданный с помощью этого кода:
var widthRange = new Array();
widthRange[46] = { min:0, max:52 };
widthRange[66] = { min:52, max:70 };
widthRange[90] = { min:70, max:94 };
Я хочу получить каждое из значений 46, 66, 90 в цикле. Я пробовал, for (var key in widthRange)
но это дает мне массу дополнительных свойств (я предполагаю, что они являются функциями объекта). Я не могу использовать обычный цикл for, поскольку значения не являются последовательными.
javascript
arrays
key
НедовольныйКозел
источник
источник
Array.prototype.forEach
. ВызовObject.keys
массива неэффективен, потому что браузеры не оптимизируют его.for(var key in array)
плохо, потому что он проходит через прототип и преобразует каждый встреченный числовой ключ в цепочку (преобразование двойных чисел в base10 очень медленное).forEach
однако был разработан именно для итерации разреженных массивов и обеспечит превосходную производительность вашего кода по сравнению с другими решениямиОтветы:
Вам нужно вызвать
hasOwnProperty
функцию, чтобы проверить, действительно ли свойство определено в самом объекте (в отличие от его прототипа), например:for (var key in widthRange) { if (key === 'length' || !widthRange.hasOwnProperty(key)) continue; var value = widthRange[key]; }
Обратите внимание, что вам нужна отдельная проверка для
length
.Однако здесь вообще не следует использовать массив; вам следует использовать обычный предмет. Все объекты Javascript функционируют как ассоциативные массивы.
Например:
var widthRange = { }; //Or new Object() widthRange[46] = { sel:46, min:0, max:52 }; widthRange[66] = { sel:66, min:52, max:70 }; widthRange[90] = { sel:90, min:70, max:94 };
источник
length
? Не помечено как[[DontEnum]]
во всех браузерах?Строковые ключи можно запрашивать с помощью
Object.keys(array)
.источник
array.keys()
ничего не вернуло.Если вы выполняете какие-либо манипуляции с массивами / коллекциями или инспектируете их, я настоятельно рекомендую использовать Underscore.js . Он небольшой, хорошо протестирован и сэкономит вам дни / недели / годы головной боли с javascript. Вот его функции клавиш:
Ключи
Получить все имена свойств объекта.
_.keys({one : 1, two : 2, three : 3}); => ["one", "two", "three"]
источник
Скажите, что ваш массив выглядел
arr = [ { a: 1, b: 2, c: 3 }, { a: 4, b: 5, c: 6 }, { a: 7, b: 8, c: 9 } ]
(или, возможно, другие ключи), вы могли бы сделатьarr.map((o) => { return Object.keys(o) }).reduce((prev, curr) => { return prev.concat(curr) }).filter((col, i, array) => { return array.indexOf(col) === i });
["a", "b", "c"]
источник
for (var i = 0; i < widthRange.length; ++i) { if (widthRange[i] != null) { // do something } }
Вы не можете получить только те ключи, которые вы установили, потому что это не так, как работает Array. После того, как вы установили элемент 46, у вас также будет установлено значение от 0 до 45 (хотя они равны нулю).У вас всегда может быть два массива:
var widthRange = [], widths = [], newVal = function(n) { widths.push(n); return n; }; widthRange[newVal(26)] = { whatever: "hello there" }; for (var i = 0; i < widths.length; ++i) { doSomething(widthRange[widths[i]]); }
редактировать ну может быть я тут весь мокрый ...
источник
widthRange.map(function(_, i) { return i });
или же
widthRange.map((_, i) => i);
источник
Ваш оригинальный пример отлично подходит для меня:
<html> <head> </head> <body> <script> var widthRange = new Array(); widthRange[46] = { sel:46, min:0, max:52 }; widthRange[66] = { sel:66, min:52, max:70 }; widthRange[90] = { sel:90, min:70, max:94 }; var i = 1; for (var key in widthRange) { document.write("Key #" + i + " = " + key + "; min/max = " + widthRange[key].min + "/" + widthRange[key].max + "<br />"); i++; } </script> </html>
Результаты в браузере (Firefox 3.6.2 в Windows XP):
Key #1 = 46; min/max = 0/52 Key #2 = 66; min/max = 52/70 Key #3 = 90; min/max = 70/94
источник
Я думаю, вам следует использовать для этого Object (
{}
), а не array ([]
).С каждым ключом связан набор данных. Он кричит об использовании объекта. Делать:
var obj = {}; obj[46] = { sel:46, min:0, max:52 }; obj[666] = { whatever:true }; // This is what for..in is for for (var prop in obj) { console.log(obj[prop]); }
Может быть, поможет какая-нибудь утилита вроде этой:
window.WidthRange = (function () { var obj = {}; return { getObj: function () {return obj;} , add: function (key, data) { obj[key] = data; return this; // enabling chaining } } })(); // Usage (using chaining calls): WidthRange.add(66, {foo: true}) .add(67, {bar: false}) .add(69, {baz: 'maybe', bork:'absolutely'}); var obj = WidthRange.getObj(); for (var prop in obj) { console.log(obj[prop]); }
источник
Кажется, работает.
var widthRange = new Array(); widthRange[46] = { sel:46, min:0, max:52 }; widthRange[66] = { sel:66, min:52, max:70 }; widthRange[90] = { sel:90, min:70, max:94 }; for (var key in widthRange) { document.write(widthRange[key].sel + "<br />"); document.write(widthRange[key].min + "<br />"); document.write(widthRange[key].max + "<br />"); }
источник
Я написал функцию, которая отлично работает с каждым экземпляром объектов (это массивы).
Object.prototype.toArray = function() { if(!this) { return null; } var c = []; for (var key in this) { if ( ( this instanceof Array && this.constructor === Array && key === 'length' ) || !this.hasOwnProperty(key) ) { continue; } c.push(this[key]); } return c; };
Применение:
var a = [ 1, 2, 3 ]; a[11] = 4; a["js"] = 5; console.log(a.toArray()); var b = { one: 1, two: 2, three: 3, f: function() { return 4; }, five: 5 }; b[7] = 7; console.log(b.toArray());
Вывод:
> [ 1, 2, 3, 4, 5 ] > [ 7, 1, 2, 3, function () { return 4; }, 5 ]
Может быть полезно кому угодно.
источник
... ????
В качестве альтернативы, если у вас есть список элементов, которые вы хотите использовать ...
var range = [46, 66, 90] , widthRange=[] , write=[]; widthRange[46] = { min:0, max:52 }; widthRange[66] = { min:52, max:70 }; widthRange[90] = { min:70, max:94 }; for(var x=0; x<range.length; x++){var key, wr; key = range[x]; wr = widthRange[key] || false; if(wr===false){continue;} write.push(['key: #',key, ', min: ', wr.min, 'max:', wr.max].join('')); }
источник
Для ваших входных данных:
let widthRange = new Array() widthRange[46] = { min:0, max:52 } widthRange[61] = { min:52, max:70 } widthRange[62] = { min:52, max:70 } widthRange[63] = { min:52, max:70 } widthRange[66] = { min:52, max:70 } widthRange[90] = { min:70, max:94 }
Декларативный подход:
const relevantKeys = [46,66,90] const relevantValues = Object.keys(widthRange) .filter(index => relevantKeys.includes(parseInt(index))) .map(relevantIndex => widthRange[relevantIndex])
Object.keys
чтобы получить ключи, используяparseInt
для преобразования их в числа.filter
получить только те, которые вам нужны.map
для создания массива из исходного объекта только тех индексов, которые вам нужны, посколькуObject.keys
теряет значения объекта.Отлаживать:
console.log(widthRange) console.log(relevantKeys) console.log(relevantValues)
источник
Вопрос довольно старый, но в настоящее время вы можете использовать forEach, который эффективен и сохраняет ключи в виде чисел:
let keys = widthRange.map((v,k) => k).filter(i=>i!==undefined))
Это проходит через widthRange и создает новый массив со значением ключей, а затем отфильтровывает все разреженные слоты, принимая только те значения, которые определены.
(Плохая идея, но для убедительности: если слот 0 всегда был пуст, его можно сократить до
filter(i=>i)
илиfilter(Boolean)
И это может быть менее эффективно, но числа можно преобразовать с помощью
let keys = Object.keys(array).map(i=>i*1)
источник