import {
isFieldNumber,
isFieldNumber2,
isgeojson,
isarrayofobjects,
} from "./helpers/helpers";
import { descending, ascending } from "d3-array";
import { autoType } from "d3-dsv";
const d3 = Object.assign({}, { descending, ascending, autoType });
/**
* @function head
* @summary Get the first n Features. The function sort data and returns the nb first elements. If a field is selected, then the function returns the top values. If the entries are strings, then the alphabetic order is applied.
* @param {object|array} data - A GeoJSON FeatureCollection or an array of objects
* @param {object} options - Optional parameters
* @param {number} [options.nb = 6] - Number of features to return
* @param {boolean} [options.key = true] - Field to sort
* @param {boolean} [options.mutate = false] - Use `true` to update the input data. With false, you create a new object, but the input object remains the same.
* @returns {object|array} - A GeoJSON FeatureCollection or an array of objects. (it depends on what you've set as `data`).
* @example
* geotoolbox.head(*a geojson or an array of objects*)
*/
export function head(data, { key, nb = 6, mutate = false } = {}) {
let x = data;
if (isgeojson(x)) {
if (!mutate) {
x = JSON.parse(JSON.stringify(data));
}
let features = [...x.features];
if (key != undefined) {
features = features
.filter((d) => d.properties[key] != "")
.filter((d) => d.properties[key] != null)
.filter((d) => d.properties[key] != undefined)
.filter((d) => d.properties[key] != +Infinity)
.filter((d) => d.properties[key] != -Infinity)
.filter((d) => d.properties[key] != NaN);
const mysort = isFieldNumber(x, key) ? d3.descending : d3.ascending;
features = features.sort((a, b) =>
mysort(
d3.autoType([String(a.properties[key])])[0],
d3.autoType([String(b.properties[key])])[0]
)
);
}
x.features = features.slice(0, nb);
} else if (isarrayofobjects(x)) {
if (key != undefined) {
x = x
.filter((d) => d[key] != "")
.filter((d) => d[key] != null)
.filter((d) => d[key] != undefined)
.filter((d) => d[key] != +Infinity)
.filter((d) => d[key] != -Infinity)
.filter((d) => d[key] != NaN);
const mysort = isFieldNumber2(x, key) ? d3.descending : d3.ascending;
x = x.sort((a, b) =>
mysort(
d3.autoType([String(a[key])])[0],
d3.autoType([String(b[key])])[0]
)
);
}
x = x.slice(0, nb);
if (mutate) {
data.splice(0, data.length, ...x);
}
}
return x;
}