From what I understood from your answers what you need is to filter the array:

Copyconst filteredArray = array.filter(element => {
    if (yourConditionIsTrue) { // if this element should be in the filteredArray
        return true;
    } else {
        return false
    }
});

Which can be done in one line:

Copyconst filteredArray = array.filter(element => conditionIsTrue);

This way your array remains untouched and you get a new array (filteredArray) only with the elements you need, but you don't mess up with the array you are iterating.

Answer from A. Llorente on Stack Overflow
🌐
TutorialsPoint
tutorialspoint.com › home › typescript › typescript array slice
TypeScript Array Slice
December 18, 2016 - TypeScript - null vs. undefined ... begin − Zero-based index at which to begin extraction. As a negative index, start indicates an offset from the end of the sequence. end − Zero-based index at which to end extraction. Returns the extracted array based on the passed parameters. var arr = ["orange", "mango", "banana", "sugar", "tea"]; console.log("arr.slice( 1, 2) : " + arr.slice( 1, 2) ); console.log("arr.slice( 1, 3) : " + arr.slice( 1, 3) );
🌐
Educative
educative.io › answers › what-is-arrayslice-in-typescript
What is array.slice() in TypeScript?
TypeScript is a superset of JavaScript. Wherever JavaScript runs, TypeScript runs, too. We can use the slice() method in TypeScript. This method is used to extract a certain section or parts of the elements of an array.
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Global_Objects › Array › slice
Array.prototype.slice() - JavaScript | MDN
The slice() method of Array instances returns a shallow copy of a portion of an array into a new array object selected from start to end (end not included) where start and end represent the index of items in that array. The original array will not be modified.
🌐
WebDevAssist
webdevassist.com › typescript › typescript-array-slice
Typescript extract a section of an array using slice
slice5 extracts from index 0 to the end of the array. ... slice1: three,four,five slice1: two,three,four,five slice3: three,four,five slice4: three slice5: one,two,three,four,five · slice copies the reference of objects.
🌐
GeeksforGeeks
geeksforgeeks.org › typescript › typescript-array-slice-method
TypeScript Array slice() Method - GeeksforGeeks
August 8, 2024 - The Array.slice() method in TypeScript is a built-in function used to extract a section of an array and return it as a new array.
🌐
HowToDoInJava
howtodoinjava.com › home › typescript › typescript array slice()
TypeScript Array slice() with Examples
August 29, 2023 - Typescript array slicing creates ... source array. ... In TypeScript, the array.slice() method extracts a section of an array (slice of an array) and returns it as a new array....
Find elsewhere
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Global_Objects › TypedArray › slice
TypedArray.prototype.slice() - JavaScript | MDN
The slice() method of TypedArray instances returns a copy of a portion of a typed array into a new typed array object selected from start to end (end not included) where start and end represent the index of items in that typed array. The original typed array will not be modified.
Top answer
1 of 6
4

"I want to create a new array containing only those objects where the property country is "United States""

This is exactly what the Array.filter() method is for:

var filteredArray = arr.filter(function(val, i, a) {
                                  return val.country==="United States";
                    });

Note that the .filter() method isn't available in IE before version 9, but the MDN page I linked to above shows you exactly how to implement it so reading that page should in itself answer your question.

Note also that in the (non-working) code in the question, your two for loops are basically doing the same thing as each other because they're both iterating over arr, so it doesn't make sense to nest them like that. You shouldn't use a for..in loop on an array, but if you do the key values will be the numeric indexes, it doesn't somehow pick up the properties of the object stored at each index.

EDIT:

"Some of the object literals have the same value for a given property, and I want to create a new array containing only those object literals."

OK, re-reading this I guess you didn't really want to select elements by specifying a country, you wanted to select elements for any country that had duplicate entries? So if there were another three elements that all had "New Zealand" you'd want to select them in addition to the "United States" ones? If so, you could do something like this:

var countryCount = {},
    i;
for (i = 0; i < arr.length; i++)
    if (countryCount.hasOwnProperty(arr[i].country)
       countryCount[arr[i].country]++;
    else
       countryCount[arr[i].country] = 1;

var filteredArr = arr.filter(function(val, i, a) {
                      return countryCount[val.country] > 1;
                  });
2 of 6
2
var getCountry = function (country) {
    var out = [];
    for (var i = 0, len = arr.length; i < len; i++)
        if (arr[i].country === country) out.push(arr[i]);
    return out;
};

Demo: http://jsfiddle.net/YwytD/1/

🌐
C# Corner
c-sharpcorner.com › UploadFile › 5089e0 › array-object-in-typescriptpart5
Array Object In TypeScript: Part 5
October 11, 2019 - The slice and concat methods let you create a new array from part of or all of an array. In either case, the original array is not modified. If you want the original array to be replaced by the new array, you can set the old array equal to the new array. ... In TypeScript, it is used to sort the array.
🌐
W3Schools
w3schools.com › jsref › jsref_slice_array.asp
JavaScript Array slice() Method
Array[ ] Array( ) at() concat() constructor copyWithin() entries() every() fill() filter() find() findIndex() findLast() findLastIndex() flat() flatMap() forEach() from() includes() indexOf() isArray() join() keys() lastIndexOf() length map() of() pop() prototype push() reduce() reduceRight() rest (...) reverse() shift() slice() some() sort() splice() spread (...) toReversed() toSorted() toSpliced() toString() unshift() values() valueOf() with() JS Boolean
🌐
Mimo
mimo.org › glossary › javascript › array-slice
JavaScript Array slice() Method: Syntax, Usage, and Examples
The slice() method returns a shallow copy of a portion of an array into a new array object, selected from a start index to an end index (end not included).
🌐
W3Resource
w3resource.com › javascript › object-property-method › array-slice.php
>JavaScript slice() Method : Array Object - w3resource
The method returns a new array and it does not change the original array, selected elements of the original array are copied into a new array. ... The starting position is required and end position is optional, if end is omitted, slice extracts ...
Top answer
1 of 2
32

Yes, you can use conditional type inference on the function type, in a way very similar to how the Parameters utility type is implemented:

type ParametersExceptFirst<F> = 
   F extends (arg0: any, ...rest: infer R) => any ? R : never;

compare to

// from lib.es5.d.ts
type Parameters<T extends (...args: any) => any> = 
  T extends (...args: infer P) => any ? P : never;

and verify that it works:

declare function foo(x: string, y: number, z: boolean): Date;
type FooParamsExceptFirst = ParametersExceptFirst<typeof foo>;
// type FooParamsExceptFirst = [y: number, z: boolean]
declare function foo(x: string, y: number, z: boolean): Date;

Playground link to code


UPDATE: arbitrary slicing of tuples with numeric literals is possible, but not pretty and has caveats. First let's write TupleSplit<T, N> which takes a tuple T and a numeric literal type N, and splits the tuple T at index N, returning two pieces: the first piece is the first N elements of T, and the second piece is everything after that. (If N is more than the length of T then the first piece is all of T and the second piece is empty):

type TupleSplit<T, N extends number, O extends readonly any[] = readonly []> =
    O['length'] extends N ? [O, T] : T extends readonly [infer F, ...infer R] ?
    TupleSplit<readonly [...R], N, readonly [...O, F]> : [O, T]

This works via recursive conditional types on variadic tuples and is therefore more computationally intensive than the relatively simple ParametersExceptFirst implementation above. If you try this on long tuples (lengths more than 25 or so) you can expect to see recursion errors. If you try this on ill-behaved types like non-fixed-length tuples or unions of things, you might get weird results. It's fragile; be careful with it.

Let's verify that it works:

type Test = TupleSplit<readonly ["a", "b", "c", "d", "e"], 3>
// type Test = [readonly ["a", "b", "c"], readonly ["d", "e"]]

Looks good.


Now we can use TupleSplit<T, N> to implement TakeFirst<T, N>, returning just the first N elements of T, and SkipFirst<T, N>, which skips the first N elements of T:

type TakeFirst<T extends readonly any[], N extends number> =
    TupleSplit<T, N>[0];

type SkipFirst<T extends readonly any[], N extends number> =
    TupleSplit<T, N>[1];

And finally TupleSlice<T, S, E> produces the slice of tuple T from start position S to end position E (remember, slices are inclusive of the start index, and exclusive of the end index) by taking the first E elements of T and skipping the first S elements of the result:

type TupleSlice<T extends readonly any[], S extends number, E extends number> =
    SkipFirst<TakeFirst<T, E>, S>

To demonstrate that this more or less represents what array slice() does, let's write a function and test it:

function slice<T extends readonly any[], S extends number, E extends number>(
    arr: readonly [...T], start: S, end: E
) {
    return arr.slice(start, end) as readonly any[] as TupleSlice<T, S, E>;
}

const tuple = ["a", "b", "c", "d", "e"] as const
// const tuple: readonly ["a", "b", "c", "d", "e"]

const ret0 = slice(tuple, 2, 4);
// const ret0: readonly ["c", "d"]
console.log(ret0); // ["c", "d"]

const ret1 = slice(tuple, 0, 9);
// const ret1: readonly ["a", "b", "c", "d", "e"]
console.log(ret1); // ["a", "b", "c", "d", "e"];

const ret2 = slice(tuple, 5, 3);
// const ret2: readonly []
console.log(ret2); // [];

This looks good; the returned arrays from slice() have types that accurately represent their values.

Of course, there are many caveats; if you pass negative or non-whole numbers to slice() for S and E, then TupleSlice<T, S, E> is very likely not to correspond to what actually happens with array slices: negative "from end" behavior is possibly implementable but it would be even uglier; non-whole numbers or even just number have not been tested but I expect recursion warnings and other things that go bump in the night. Be warned!

Playground link to code

2 of 2
0

@jcalz accepted solution here has a limitation: it drops tuple labels:

type OriginalTupleSplit = TupleSplit<[a: 1, b: 2, c: 3, d: 4, e: 5], 2> 
// [[1, 2], [c: 3, d: 4, e: 5]]

Below is a modified version that doesn't do that:

type TupleSplitHead<T extends any[], N extends number> = T['length'] extends N
  ? T
  : T extends [...infer R, any]
  ? TupleSplitHead<R, N>
  : never

type TupleSplitTail<T, N extends number, O extends any[] = []> = O['length'] extends N
  ? T
  : T extends [infer F, ...infer R]
  ? TupleSplitTail<[...R], N, [...O, F]>
  : never

type TupleSplit<T extends any[], N extends number> = [TupleSplitHead<T, N>, TupleSplitTail<T, N>]

type ModifiedTupleSplit = TupleSplit<[a: 1, b: 2, c: 3, d: 4, e: 5], 2>
// [[a: 1, b: 2], [c: 3, d: 4, e: 5]]

code

This is less performant than @jcalz's solution - as it iterates the array twice, but it keeps the labels.

🌐
Fjolt
fjolt.com › article › javascript-slice
Javascript Array Slice Method
The slice method is used to return shallow copies of arrays based on optional start and end arguments. Shallow copies contain the same reference as the original array sliced.
🌐
ReqBin
reqbin.com › code › javascript › kvmd5zzt › javascript-array-slice-example
How do I slice a JavaScript array?
The array.slice(start, end) method returns a shallow copy of the array containing a portion of the original array. A shallow copy is an exact copy of the original object's values one level deep.