фильтровать массив объектов по нескольким условиям - PullRequest
0 голосов
/ 03 июля 2019

У меня есть этот массив

const d = [{
    "type": "price",
    "value": {
        "min": 0,
        "max": 170
    }
}, {
    "type": "name",
    "value": {}
}, {
    "type": "volume",
    "options": [1,2]
}]

Я хочу отфильтровать, если значение не имеет значения или параметры являются пустым массивом.Итак, я сделал

d.filter(o => o.value || o.options)

Я ожидаю, что type:name пропал, но почему он все еще там?

Я также попробовал lodash

d.filter(o => !isEmpty(o.value) || !isEmpty(o.options))

не работает должным образом

Ответы [ 5 ]

2 голосов
/ 03 июля 2019

{} и [] - истинные значения

console.log(Boolean([]))
console.log(Boolean({}))

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

const d = [{"type": "price","value": {"min": 0,"max": 170}}, {"type": "name","value": {}}, {"type": "volume","options": [1,2]}]

let op = d.filter(o => ( Object.values(o.value || {}) || (o.options || [] )).length)

console.log(op)
0 голосов
/ 03 июля 2019

С lodash вы можете использовать _.reject() с _.isEmpty() для удаления элементов, имеющих пустой объект value и пустой массив options:

const arr = [{"type": "price","value": {"min": 0,"max": 170}}, {"type": "name","value": {}}, {"type": "volume","options": [1,2]}]

const result = _.reject(arr, o => _.isEmpty(o.value) && _.isEmpty(o.options))

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

С помощью lodash / fp вы можете легко сгенерировать функцию, которая извлекает value и options, повторяет их с помощью _.every() и возвращает true (должен быть удален), если оба они пусты:

const { reject, flow, props, every, isEmpty } = _

const fn = reject(flow(props(['value', 'options']), every(isEmpty)))

const arr = [{"type": "price","value": {"min": 0,"max": 170}}, {"type": "name","value": {}}, {"type": "volume","options": [1,2]}]

const result = fn(arr)

console.log(result)
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>
0 голосов
/ 03 июля 2019

Дайте пользовательский фильтр обратного вызова, где вы проверяете любое свойство entry в values и options.

const d = [
	{
		"type": "price",
		"value": {
			"min": 0,
			"max": 170
		}
	}, 
	{
		"type": "name",
		"value": {}
	}, 
	{
		"type": "volume",
		"options": [1,2]
	}
];


function doesHaveValuesAndOptions(obj) {
	const valueEntries = obj.value ? Object.entries(obj.value) : [],
		    options = obj.options || [];
	
	if (!valueEntries.length && !options.length)
		return false;
	
	else if (valueEntries.length || options.length)
		return true;
	
	return false;
}



const res = d.filter(doesHaveValuesAndOptions);
console.log(res);
0 голосов
/ 03 июля 2019

Вот мое решение.

const d = [{
    "type": "price",
    "value": {
        "min": 0,
        "max": 170
    }
}, {
    "type": "name",
    "value": {}
}, {
    "type": "volume",
    "options": [1,2]
}]

function notEmpty(n){
   return (!!n ? typeof n === 'object' ? Array.isArray(n) ? !!n.length : !!Object.keys(n).length : true : false);
}

console.log(d.filter(o => notEmpty(o.value) || notEmpty(o.options)));

Надежда поможет вам.

0 голосов
/ 03 июля 2019

{} - все еще истинное значение, вы должны проверить длину его ключей

const d = [{
    "type": "price",
    "value": {
        "min": 0,
        "max": 170
    }
}, {
    "type": "name",
    "value": {}
}, {
    "type": "volume",
    "options": [1,2]
}]

console.log(d.filter(o => (o.value && Object.keys(o.value).length) || o.options))
...