Я только начал использовать crossfilter. У меня мало опыта работы с данными.
Мои данные выглядят так:
const data = [
{_id: 001, a: 10, b: 11, c: 12},
{_id: 002, a: 11, c: 13},
{_id: 003, b: 12, c: 14},
{_id: 004, f: 102 },
{_id: 005, e:100, f:101, g: 102}
];
Как вы можете видеть, не каждый объект имеет одинаковые или общие ключи. Я получаю неправильные значения для
dimension.top(), dimension.bottom()
Например:
const by_a = cf.dimension(function(d){return d.a};
const max_a = by_a.top(1)[0];
// Should be max_a = { _id: 002, a: 11, c: 13}
// Instead returns wrong object,
const by_f = cf.dimension(function(d){return d.f};
const min_f = by_f.bottom(1)[0];
// Should be min_f = { _id: 004, e:100, f:101, g: 102}
// Wrong object again.
Я прочитал Crossfilter Gotchas, но не могу понять, применимо ли к этому какое-либо из этих случаев, или же у такого случая есть решение вообще. Я тоже не сталкивался с подобным вопросом. Я хотел бы иметь возможность запускать базовые запросы перекрестного фильтра. Буду признателен за любую оказанную помощь. Благодарю.
Да, это точно одна из проблем. Если вы попытаетесь прочитать поле в JavaScript и его там нет, значение по умолчанию не undefined
.
Тогда, если вы сравните это с числом, он будет принуждать NaN
.
И NaN
всегда сравнивает ложь, которая закручивает алгоритмы сортировки.
Если вы определяете свою ключевую функцию следующим образом, вы должны получить желаемое (или, по крайней мере, предсказуемое) поведение:
const by_a = cf.dimension(function(d){return d.a || 0; };
Или, если вы хотите, чтобы они всегда были внизу, даже при наличии отрицательных чисел:
const by_a = cf.dimension(function(d){return d.a || -Infinity; };
Я добавил пример к "естественному заказу".
Вот мои результаты, следующие за советом Гордона. Рассмотрим следующий набор данных:
const data = [
{_id: "001", a: 10, b: 11, c: 12},
{_id: "002", a: 11, c: 13},
{_id: "003", a:-11, c: 13},
{_id: "004", a: 0, c: 13},
{_id: "005", b: 12, c: 14},
{_id: "006", f: 102 },
{_id: "007", e:100, f: 101,g: 102}
];
Использование обратного вызова, возвращающего значение по умолчанию, равное нулю, если поле отсутствует:
// Where dim is the field I'm dimensioning the data by
const by_dim = cf.dimension( d => d.dim || 0 );
// Logging the results of by_a.top(7)
0:{_id: "002", a: 11, c: 13} // Correct
1:{_id: "001", a: 10, b: 11, c: 12} //Correct
2:{_id: "007", e: 100, f: 101, g: 102} //Incorrect
3:{_id: "006", f: 102}
4:{_id: "005", b: 12, c: 14}
5:{_id: "004", a: 0, c: 13} //Should have been at index 2
6:{_id: "003", a: -11, c: 13} // Should have been at index 3
// Logging the results of by_a.bottom(7)
0:{_id: "003", a: -11, c: 13} // Correct
1:{_id: "004", a: 0, c: 13} // Correct
2:{_id: "005", b: 12, c: 14} // Incorrect
3:{_id: "006", f: 102}
4:{_id: "007", e: 100, f: 101, g: 102}
5:{_id: "001", a: 10, b: 11, c: 12} //Should have been at index 2
6:{_id: "002", a: 11, c: 13} //Should have been at index 3 ..
Кажется, что возвращаемое значение 0
в вопросе обратного ответа при отсутствии поля помещает эти объекты между объектами, содержащими это поле, со значением >0
и =< 0
. Но это отлично работает для меня, потому что я могу просто отфильтровать объекты, не содержащие рассматриваемого измерения, используя Lodash или другую библиотеку.
Благодарю.
-Infinity
вместо этого - добавил это в мой ответ.
dimension.top(n)
всегда будет возвращать правильный массив?