JavaScript: Как я могу получить все ключи и значения объекта, которые начинаются с определенной строки?
Я пытаюсь получить все ключи и значения объекта, начинающегося с imageIds
.
Мой объект выглядит следующим образом:
{
title: 'fsdfsd',
titleZh: 'fsdfsd',
body: 'fsdf',
bodyZh: 'sdfsdf',
imageIds: '/uploads/tmp/image-3.png',
imageIdsZh: ''
}
но мне нужны только свойства imageIds
и imageIdsZh
. Однако завтра объект может содержать imageIdsBlah
, и мне тоже нужно будет его поднять. Я мог удалить первые несколько свойств из объекта, но затем следующий объект может содержать дополнительные свойства, такие как foo: 'bar'
Ответы
Ответ 1
Некоторая функциональная стильность:
var data = {
title: 'fsdfsd',
titleZh: 'fsdfsd',
body: 'fsdf',
bodyZh: 'sdfsdf',
imageIds: '/uploads/tmp/image-3.png',
imageIdsZh: ''
};
var z = Object.keys(data).filter(function(k) {
return k.indexOf('imageIds') == 0;
}).reduce(function(newData, k) {
newData[k] = data[k];
return newData;
}, {});
console.log(z);
Демо: http://jsfiddle.net/ngX4m/
Некоторые незначительные объяснения:
- Мы используем функцию
Array.prototype.filter()
для фильтрации ключей, начинающихся с `imageIds2
- Мы используем
Array.prototype.reduce()
для преобразования массива фильтрованных ключей в объект пар key-value
. Для этого мы используем начальное значение {}
(пустой объект), заполняем его и возвращаем с каждого этапа выполнения.
UPD
Яркое обновление от @GitaarLAB:
Object.keys
является ES5, но возвращает собственные свойства объектов (поэтому нет необходимости в obj.hasOwnProperty(key)
)
Ответ 2
В зависимости от того, насколько велик объект, это может плохо масштабироваться, но оно будет работать
for(key in obj){
if(obj.hasOwnProperty(key)){
if(key.indexOf("imageIds")===0){
//do something
}
}
}
Ответ 3
Также нужно использовать hasOwnProperty
в сочетании с циклом for-in (не упомянутым в большинстве предыдущих текущих ответов).
Причина в том, что цикл for-in также будет переходить методы/свойства, которые объект наследует от прототипной цепочки (если кто-то или какая-то библиотека добавили пользовательские материалы).
Итак, вы ищете что-то простое и надежное:
function fetch(obj, str){
var key, results = [];
for(key in obj) obj.hasOwnProperty(key)
&& key.indexOf(str) === 0
&& results.push([ key, obj[key] ]);
return results;
}
Примечание: вы также можете назвать эту функцию "getAllKeysAndValuesStartingWith" (или gakavsw, если вы работаете в армии ха-ха).Суб >
Применение:
fetch(object, string)
возвращает простой (в цикл) массив с найденными результатами,
поэтому var my_results = fetch(testObj, 'imageId');
даст следующий результат:
[ //array of arrays
['imageIds', '/uploads/tmp/image-3.png']
, ['imageIdsZh', ''] /*
, [key, value] and more if it finds them */
]
Работаем jsfiddle здесь.
Естественно, можно также нажать только значения: results.push(obj[key])
Я бы рекомендовал не возвращать объект ((results[key]=obj[key])
), так как в этом случае проще работать с массивом.
Надеюсь, это поможет!
Ответ 4
По строкам ответа от @zerkms, я работал над библиотека функционального программирования для Javascript. Благодаря инструментам из этой библиотеки это превращается в (несколько плотный) однострочный слой:
var data = {
title: 'fsdfsd',
titleZh: 'fsdfsd',
body: 'fsdf',
bodyZh: 'sdfsdf',
imageIds: '/uploads/tmp/image-3.png',
imageIdsZh: ''
};
var x = pick(filter(compose(eq("imageIds"), substring(0,8)), keys(data)), data);
console.log(x);
Этот код не обязательно лучше, чем @zerkms, но он демонстрирует еще некоторые возможности функциональных абстракций кроме тех, которые встроены в Array.prototype
.
Вы можете видеть его в действии на JSFiddle.
Ответ 5
// json to be searched
var data = {
title: 'fsdfsd',
titleZh: 'fsdfsd',
body: 'fsdf',
bodyZh: 'sdfsdf',
imageIds: '/uploads/tmp/image-3.png',
imageIdsZh: ''
};
// takes the json 'data' as its 1st parameter
// and the desired 'property' to be searched as the 2nd parameter
// for loop iterates through the entire json
// if the property parameter matches a 'key' name in json e.g. 'imageIds'
// then the value for that property is returned
function fetchProperty (data, property) {
for(var key in data) {
if(key === property) {
return data[key];
}
}
}
// if you wanted to return a bunch of data according to a particular key - value pair
// you could do something like this...
// assume 'array' contains a bunch of jsons
// newData will hold jsons containing your newly fetched data points
function fetchNewData() {
var newData = [];
for(var i = 0; i < array.length; i++) {
var value1 = fetchProperty(array[i], 'imageIds');
var value2 = fetchProperty(array[i], 'imageIdsZh');
var value3 = fetchProperty(array[i], 'imageIdsBlah');
var tempJSON = {};
tempJSON.imageIds = value1;
tempJSON.imageIdsZh = value2;
tempJSON.imageIdsBlah = value3;
newData.push(tempJSON);
}
return newData;
}
** Надеюсь, это было полезно. Если у вас возникнут дополнительные вопросы, не стесняйтесь обращаться к ним. Удачи. **