У меня есть такая структура данных:
var someObject = {
'part1' : {
'name': 'Part 1',
'size': '20',
'qty' : '50'
},
'part2' : {
'name': 'Part 2',
'size': '15',
'qty' : '60'
},
'part3' : [
{
'name': 'Part 3A',
'size': '10',
'qty' : '20'
}, {
'name': 'Part 3B',
'size': '5',
'qty' : '20'
}, {
'name': 'Part 3C',
'size': '7.5',
'qty' : '20'
}
]
};
И я хотел бы получить доступ к данным с помощью этих переменных:
var part1name = "part1.name";
var part2quantity = "part2.qty";
var part3name1 = "part3[0].name";
part1name должно быть заполнено someObject.part1.name
значением ', которое является "Часть 1". То же самое с part2quantity, который заполнен 60.
Есть ли способ достичь этого с помощью чистого JavaScript или JQuery?
javascript
jquery
path
nested
Komaruloh
источник
источник
var part1name = someObject.part1name;
`Ответы:
Я только что сделал это, основываясь на некотором похожем коде, который у меня уже был, похоже, он работает:
Применение::
Смотрите рабочую демонстрацию на http://jsfiddle.net/alnitak/hEsys/
EDIT некоторые заметили, что этот код выдаст ошибку, если передать строку, где крайние левые индексы не соответствуют правильно вложенной записи в объекте. Это действительная проблема, но IMHO лучше всего решать с
try / catch
блоком при вызове, вместо того, чтобы эта функция молча возвращалаundefined
неверный индекс.источник
_.get(object, nestedPropertyString);
'part3[0].name.iDontExist'
. Добавление проверки, чтобы видеть,o
является ли объект вif in
исправлении проблемы. (Как вы поступите, это зависит от вас). Смотрите обновленную скрипку: jsfiddle.net/hEsys/418Это решение, которое я использую:
Пример использования:
Ограничения:
[]
) для индексов массива, хотя указание индексов массива между токеном-разделителем (например,.
) работает нормально, как показано выше.источник
_.reduce()
Reduce - отличное решение (его также можно использовать из библиотеки подчеркивания или lodash)self
, вероятно, здесь не определено. Вы имеете в видуthis
?Теперь это поддерживается с помощью lodash
_.get(obj, property)
. Смотрите https://lodash.com/docs#getПример из документов:
источник
_.set(...)
_.get
будет демонстрировать то же поведение, что и в том случае, если в предоставленном объекте не найдено ни одного ключа. например_.get(null, "foo") -> undefined
,_.get(null, "foo", "bar") -> "bar"
. Однако это поведение не определено в документах, поэтому может быть изменено.ES6 : только одна строка в Vanila JS (она возвращает ноль, если не находит вместо сообщения об ошибке):
Или пример:
С дополнительным оператором цепочки :
Для готовой к использованию функции, которая также распознает false, 0 и отрицательное число и принимает значения по умолчанию в качестве параметра:
Пример использования:
Бонус :
Чтобы установить путь (запрашивается @ rob-gordon), вы можете использовать:
Пример:
Доступ к массиву с помощью [] :
Пример:
источник
let o = {a:{b:{c:1}}}; let str = 'a.b.c'; str.split('.').splice(0, str.split('.').length - 1).reduce((p,c)=>p&&p[c]||null, o)[str.split('.').slice(-1)] = "some new value";
0
,undefined
иnull
значения.{a:{b:{c:0}}}
возвращаетсяnull
вместо0
. Возможно, явная проверка на null или undefined устранит эти проблемы.(p,c)=>p === undefined || p === null ? undefined : p[c]
Reflect.has(o, k) ? ...
(ES6 Reflect.has ) работаетsetPath
установит значение при первом появлении последнего селектора. Например,let o = {}; setPath(o, 'a.a', 0)
результаты,{a: 0}
а не{a: {a: 0}}
. см. этот пост для решения.Вы должны разобрать строку самостоятельно:
Для этого необходимо также определить индексы массива с точечной нотацией:
Это облегчает анализ.
DEMO
источник
[]
синтаксиса в синтаксис свойства довольно тривиально.while (l > 0 && (obj = obj[current]) && i < l)
то этот код работает и для строк без точек.Работает для массивов / массивов внутри объекта также. Защита от недопустимых значений.
источник
используя eval:
обернуть, чтобы вернуть неопределенное при ошибке
http://jsfiddle.net/shanimal/b3xTw/
Пожалуйста, руководствуйтесь здравым смыслом и осторожностью при использовании силы пробуждения. Это немного похоже на легкую саблю, если вы включите ее, есть 90% -ный шанс, что вы отрежете конечность. Это не для всех.
источник
Вы можете получить значение элемента глубокого объекта с точечной нотацией без какой-либо внешней библиотеки JavaScript с помощью простого трюка:
В вашем случае , чтобы получить значение
part1.name
отsomeObject
просто сделать:Вот простая демонстрация скрипки: https://jsfiddle.net/harishanchu/oq5esowf/
источник
Это, вероятно, никогда не увидит свет ... но здесь это в любом случае.
[]
синтаксис скобки.
.
персонажаundefined
)источник
Это один лайнер с lodash.
Или даже лучше ...
Или версия ES6 с уменьшением ...
Plunkr
источник
Я думаю, что вы просите об этом:
Вы могли бы просить об этом:
Оба из которых будут работать
Или, может быть, вы просите об этом
Наконец, вы могли бы попросить об этом
источник
Split
метода, а скорееsplit
.Здесь я предлагаю больше способов, которые кажутся более быстрыми во многих отношениях:
Вариант 1: разделить строку на. или [или] или 'или ", переверните его, пропустите пустые элементы.
Вариант 2 (самый быстрый, кроме
eval
): Низкоуровневое сканирование символов (без регулярных выражений / разбиений / и т. Д., Просто быстрое сканирование символов). Примечание: этот не поддерживает кавычки для индексов.Вариант 3: ( новый : расширен вариант 2 для поддержки кавычек - немного медленнее, но все же быстро)
JSPerf: http://jsperf.com/ways-to-dereference-a-delimited-property-string/3
"eval (...)" все еще король (хотя производительность). Если у вас есть пути к свойствам непосредственно под вашим контролем, не должно быть проблем с использованием 'eval' (особенно, если вам нужна скорость). Если вы перетаскиваете пути свойств «по проводу» ( на линии !? Lol: P), тогда да, используйте что-то еще, чтобы быть в безопасности. Только идиот сказал бы, что никогда не должен использовать «eval», так как есть веские причины, чтобы его использовать. Кроме того, «Он используется в JSON-парсере Дуга Крокфорда» . Если вход безопасен, то никаких проблем нет. Используйте правильный инструмент для правильной работы, вот и все.
источник
На всякий случай, кто-нибудь посетит этот вопрос в 2017 году или позже и ищет легкий для запоминания способ, вот подробный пост в блоге о доступе к вложенным объектам в JavaScript без обмана со стороны
Невозможно прочитать свойство 'foo' из неопределенного ошибкой
Доступ к вложенным объектам с помощью Array Reduce
Давайте возьмем этот пример структуры
Чтобы иметь доступ к вложенным массивам, вы можете написать свой собственный массив execute.
Также есть отличная минимальная библиотека для обработки типов типов которая сделает все это за вас.
С typy ваш код будет выглядеть так
Отказ от ответственности: я являюсь автором этого пакета.
источник
AngularJS
Подход Спейгга очень аккуратный и чистый, хотя я нашел этот ответ, когда искал решение для доступа к свойствам области видимости AngularJS $ по строковому пути, и с небольшой модификацией он выполняет свою работу:
Просто поместите эту функцию в свой корневой контроллер и используйте любую дочернюю область, например:
источник
$scope.$eval
еще один способ сделать это с AngularJS.Я еще не нашел пакет, который выполнял бы все операции со строковым путем, поэтому я написал свой собственный небольшой пакет, который поддерживает insert (), get () (с возвратом по умолчанию), set () и remove ( ) операции.
Вы можете использовать точечные обозначения, скобки, числовые индексы, свойства строковых чисел и ключи с несловесными символами. Простое использование ниже:
https://www.npmjs.com/package/jsocrud
https://github.com/vertical-knowledge/jsocrud
источник
Работает с
источник
Простая функция, допускающая либо строку, либо путь к массиву.
ИЛИ
источник
npm
Теперь для этого есть модуль: https://github.com/erictrinh/safe-accessПример использования:
источник
Хотя уменьшение это хорошо, я удивлен, что никто не использовал forEach:
Тестовое задание
источник
a.b.c
возникнет исключение, еслиb
в вашем объекте нет свойства . Если вам нужно что-то молча отклонить неверный путь к клавиатуре (что я не рекомендую), вы все равно можете заменить forEach на этотkeys.forEach((key)=> obj = (obj||{})[key]);
Недавно у меня был тот же вопрос, и он успешно использовал https://npmjs.org/package/tea-properties, который также
set
вложил объект / массив:получить:
набор:
источник
Вдохновленный ответом @ webjay: https://stackoverflow.com/a/46008856/4110122
Я сделал эту функцию, которую вы можете использовать для получения / установки / сброса любого значения в объекте
Чтобы использовать это:
источник
Я занимаюсь разработкой интернет-магазина с React. Я попытался изменить значения в скопированном объекте состояния, чтобы обновить исходное состояние с ним при отправке. Приведенные выше примеры не сработали, потому что большинство из них изменяют структуру копируемого объекта. Я нашел рабочий пример функции для доступа и изменения значений свойств глубоко вложенного объекта: https://lowrey.me/create-an-object-by-path-in-javascript-2/ Вот это:
источник
На основании ответа Алнитак .
Я завернул полифилл в чек и уменьшил функцию до одного цепного сокращения.
источник
Если вам нужно получить доступ к другому вложенному ключу, не зная его во время кодирования (это будет тривиально, обратиться к ним), вы можете использовать средство доступа к записи массива:
Они эквивалентны аксессору с точечной нотацией и могут изменяться во время выполнения, например:
эквивалентно
или
Я надеюсь, что это ответить на ваш вопрос ...
РЕДАКТИРОВАТЬ
Я не буду использовать строку для поддержки своего рода запроса xpath для доступа к значению объекта. Так как вам нужно вызвать функцию для анализа запроса и получения значения, я бы пошел по другому пути (не:
или, если вас не устраивает метод применения
Функции короче, понятнее, интерпретатор проверяет их на наличие синтаксических ошибок и так далее.
Кстати, я чувствую, что простого задания, сделанного в нужное время, будет достаточно ...
источник
Решения здесь просто для доступа к глубоко вложенным ключам. Мне нужен был один для доступа, добавления, изменения и удаления ключей. Вот что я придумал:
path_to_key
: путь в массиве. Вы можете заменить его своимstring_path.split(".")
.type_of_function
: 0 для доступа (не передавайте никакое значениеvalue
), 0 для добавления и изменения. 1 для удаления.источник
Построение ответа Альнитака:
}
Это позволяет вам также установить значение!
Я создал пакет npm и github с этим
источник
Вместо строки можно использовать массив для адресации вложенных объектов и массивов, например:
["my_field", "another_field", 0, "last_field", 10]
Вот пример, который может изменить поле на основе этого представления массива. Я использую что-то подобное вact.js для контролируемых полей ввода, которые изменяют состояние вложенных структур.
источник
Основываясь на предыдущем ответе, я создал функцию, которая также может обрабатывать скобки. Но нет точек внутри них из-за раскола.
источник
источник
Работа с
Underscore
«sproperty
илиpropertyOf
:Удачи...
источник